この記事は、Uncle_Tom によって Huawei クラウド コミュニティ「Application Security Protection ESAPI」から共有されたものです。
1. ESAPI の概要
OWASP Enterprise Security API (ESAPI) は、プログラマーがリスクの低いアプリケーションを簡単に作成できるようにする、Web アプリケーション セキュリティ制御の無料のオープン ソース ライブラリです。ESAPI ライブラリは、プログラマがセキュリティのために既存のアプリケーションを簡単に改良できるように設計されています。ESAPI ライブラリは、新しい開発のための強固な基盤でもあります。
言語固有の違いを考慮して、すべての OWASP ESAPI バージョンは同じ基本設計を持っています。
- 一連のセキュリティ制御インターフェイスがあります。たとえば、セキュリティ制御タイプに渡されるパラメータ タイプを定義します。
- 各セキュリティ制御にはリファレンス実装があります。例: 文字列ベースの入力検証。たとえば、Java の ESAPI org.owasp.ESAPI.reference.FileBasedAuthenticator は、 org.oasp.ESAPI.reference.DefaultEncoder や org.owasp.ESAPI.reference.DefaultValidator など、他のリファレンス実装は成熟したエンタープライズ レベルのリファレンス実装です。
- 各セキュリティ制御には独自の実装があります (オプション)。これらのクラスには、組織によって、または組織のために開発されたアプリケーション ロジックが含まれる場合があります。例: エンタープライズ認証。
- このプロジェクトをできるだけ普及しやすく、より多くの人が自由に使えるようにするため、このプロジェクトのソースコードはBSDライセンスを使用しています。このプロジェクトのドキュメントは、クリエイティブ コモンズ表示ライセンスに基づいてライセンスされています。ESAPI は自由に使用、変更でき、商用製品に組み込むこともできます。
2.ESAPIフレームワーク
OWASP ESAPI は次のセキュリティ制御を実装しています。
- 認証
- アクセス制御
- 入力の検証
- 出力のエンコード/エスケープ
- パスワード
- エラー処理とログ記録
- 通信安全
- HTTPセキュリティ
- セキュリティ設定
ESAPIフレームワーク
ESAPI がカバーする OWASP トップ 10
3. ESAPIの利用
3.1. pom.xml での ESAPI 設定
最新バージョンは 2.5.3.1 で、Maven リポジトリに直接あります。
<!-- https://mvnrepository.com/artifact/org.owasp.esapi/esapi --> <依存関係> <groupId>org.owasp.esapi</groupId> <artifactId>esapi</artifactId> <バージョン> 2.5.3.1</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <!-- https ://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <依存関係> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <バージョン>3.1 .0</version> <scope>提供</scope> </dependency>
3.2. インジェクションの問題に対する保護
ネットワーク セキュリティの問題の大部分は、インジェクションの問題によって引き起こされます。このタイプの問題は主に、SQL インジェクション、コマンド インジェクション、クロスサイト スクリプティングなどの外部入力使用時の不適切なトランスコーディングによって発生します。
Encode (エンコーダ インターフェイス) には、処理された文字がさまざまなインタプリタにとって安全であるように、入力をデコードし出力をエンコードするためのメソッドが多数含まれています。
3.2.1. 保護: XSS クロスサイト スクリプティング攻撃
HTML エンコーダ (encodeForHTML)
@Test void testEncodeForHTML() { String input = "<a href='sdfs'></a> < script >alert('xss'); </ script >"; 文字列 encodedString = ESAPI.encoder().encodeForHTML(input); LOG.info("EncodeForHTML: {}", encodedString); }
出力:
EncodeForHTML: <a href='xss'></a> <; スクリプト > アラート('xss'); </ スクリプト >
URL エンコーダ (encodeForURL)
@Test void testEncodeForURL() { String input = "/?callback=<script>alert('xss')</script>"; 文字列エンコードされた文字列; { encodedString = ESAPI.encoder().encodeForURL(input);を試してください。 LOG.info("EncodeForURL: {}", encodedString); catch (EncodingException e) { fail("例外を取得しないでください:" + e.getMessage()); } }
出力:
EncodeForURL: %2F%3Fcallback%3D%3Cscript%3Ealert%28%27xss%27%29%3C%2Fscript%3E
3.2.2. 保護: SQL インジェクション
@Test void testEncodeForSQL() { String userId = "tom" または '1=1'"; String sql = "select * from user where user='" + ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.Mode.STANDARD), userId) + "'"; LOG.info("sql = {}", sql); }
出力:
sql = select * from user where user='tom\' または \'1\=1\''
3.2.3. 保護: コマンドインジェクション
@Test void testEncodeForOS() { String input = "dir & dir /s"; 文字列 cmd = ESAPI.encoder().encodeForOS(new WindowsCodec(), input); LOG.info("cmd = {}", cmd); }
出力:
cmd = dir^ ^&^ dir^ ^/s
3.3. 入力検証の問題に対する保護
ネットワーク セキュリティに対する最大の脅威は外部入力であるため、外部入力の検証はアプリケーション セキュリティにおいて最大の保護の役割を果たします。
3.3.1. ESAPI入力の検証
ESAPI には入力検証設定があります。validation.properties は一般的に使用される検証を提供します。
検証.プロパティ
Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$ Validator.Email=^[A-Za-z0-9._%'-]+@[A- Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][ 0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]| [01]?[0-9][0-9]?)$ Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z] ([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\ .\\?\\,\\:\\'\\/\\\\\\+=&;%\\$#_]*)?$ Validator.CreditCard=^(\\d{4}[ - ]?){3}\\d{4}$ Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[ 012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
検証インターフェース
/** * 入力検証 * * @param コンテキスト検証内容 * @param 入力検証入力 * @param 型検証タイプ、validation.properties の型に対応 * @param maxLength 入力文字の最大長検証 * @paramallowNull 入力文字 Null値の検証、false - 許可されません; true - 許可 * @return 検証が失敗した場合は false を返し、検証が成功した場合は true を返します */ boolean ESAPI.validator().getValidInput(String context, String input, String type , int maxLength, boolean allowedNull );
@Test void testValidatorEmail() { 文字列入力 = "xxxx.com"; if (!ESAPI.validator().isValidInput("", input, "電子メール", 11, false)) { LOG.error("電子メールの検証に失敗しました!"); } else { LOG.info("電子メールは検証されています。"); } }
出力:
電子メールの検証に失敗しました!
4. ESAPI の使用およびアップグレード中に発生する一般的な問題
4.1. org.owasp.esapi.reference.DefaultEncoder CTOR が ExceptionInInitializerError によって例外をスローしました
org.owasp.esapi.errors.ConfigurationException: java.lang.reflect.InvocationTargetException エンコーダ クラス (org.owasp.esapi.reference.DefaultEncoder) CTOR が例外をスローしました。 org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:129) で org.owasp.esapi.ESAPI.encoder(ESAPI.java:101) で com.test.esapi.EsapiTest.testUpdateJulietInfo_good(EsapiTest.java) :19) java.base/java.util.ArrayList.forEach(ArrayList.java:1511) で java.base/java.util.ArrayList.forEach(ArrayList.java:1511) 原因: java.lang.reflect。 org.owasp.esapi.util.ObjFactory.make(ObjFactory.java:86) のInvocationTargetException ... 71 詳細 原因: java.base/java.lang.Class.forName0(Native Method) の java.lang.ExceptionInInitializerError java.base/java.lang.Class.forName(Class.java:375) at org.owasp.esapi.util.ObjFactory.loadClassByStringName(ObjFactory.java:158) at org.owasp.esapi.util.ObjFactory.make( ObjFactory.java:81) org.owasp.esapi.ESAPI.logFactory(ESAPI.java:139) org.owasp.esapi.ESAPI.getLogger(ESAPI.java:155) org.owasp.esapi.reference.DefaultEncoder .(DefaultEncoder.java:85) at org.owasp.esapi.reference.DefaultEncoder.(DefaultEncoder.java:109) at org.owasp.esapi.reference.DefaultEncoder.getInstance(DefaultEncoder.java:68) ... 76 詳細 原因: org.owasp.esapi.errors.ConfigurationException: リソースが見つかりません: esapi-java-logging.properties at org.owasp.esapi.logging.java.JavaLogFactory.readLoggerConfiguration(JavaLogFactory.java:128) at org.owasp .esapi.logging.java.JavaLogFactory.(JavaLogFactory.java:96) ... 85 詳細
これは、ESAPI を 2.5.0.0 以降のバージョンにアップグレードするときに発生する最も一般的な問題です。
2.5.0.0 は ESAPI の重要な変更バージョンです。バージョン変更情報から次のことがわかります。
- このバージョンの ESAPI は、Log4J の絶え間ない脆弱性に悩まされている Log4J のサポートを完全に放棄し、代わりに SLF4J を使用します。ESAPI.Logger プロパティが Log4J を使用するように設定されている場合、変更しないと、不明瞭な例外またはエラー (通常は ExceptionInInitializerError) がスローされます。
- AntiSamy は 1.7.0 にアップグレードされ、AntiSamy のカスタマイズされた AntiSamy-sapi.xml ファイルがサポートされています。
- 前のバージョンと同様、このバージョンでも Java 8 以降のみがサポートされます。
ここから、ExceptionInInitializerError は変更ログ コンポーネントによって発生することがわかります。詳しい人は、すべてのコンポーネントの構成を示す ESAPI の構成ファイル、ESAPI.properties をすぐに思い浮かべるでしょう。
図の 69 行目から 72 行目からわかるように、69 行目は次のようになります。
ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory
まだ org.owasp.esapi.logging.java.JavaLogFactory を指していますが、次のコメントも 71 行目に変更する必要があることを示しています。
ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
修正後、問題は解決されました。
4.2. java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest at java.base/java.lang.Class.getDeclaredMethods0(Native Method) at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) at java .base/java.lang.Class.getMethodsRecursive(Class.java:3543) java.base/java.lang.Class.getMethod0(Class.java:3529) java.base/java.lang.Class.getMethod(Class .java:2225) org.owasp.esapi.util.ObjFactory.loadMethodByStringName(ObjFactory.java:196) org.owasp.esapi.util.ObjFactory.findSingletonCreateMethod(ObjFactory.java:173) org.owasp.esapi で。 util.ObjFactory.make(ObjFactory.java:84) at org.owasp.esapi.ESAPI.validator(ESAPI.java:192) at com.huawei.hwe.esapi.EsapiTest.testEsapi_encodeForURL(EsapiTest.java:23) at java .base/java.util.ArrayList.forEach(ArrayList.java:1511) java.base/java.util.ArrayList.forEach(ArrayList.java:1511) 原因: java.lang.ClassNotFoundException: javax.servlet.http .HttpServletRequest java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) java.base /java.lang.ClassLoader.loadClass(ClassLoader.java:525) ... 79 詳細
この問題では、明らかに依存ライブラリが欠落しています。Maven ライブラリの定義と ESAPI に関する依存関係情報を表示できます。
https://mvnrepository.com/artifact/org.owasp.esapi/esapi/2.5.3.1
コンパイルの依存関係
実行時の依存関係

実行中の依存関係から、要件: javax.servlet » javax.servlet-api を確認できます。
バージョン番号: 3.1.0 をクリックして、javax.servlet-api 3.1.0 の mvn 依存関係構成を取得します。この構成を次の場所に追加します。その上のプロジェクト pom.xml ファイル。
pom.xml に javax.servlet-api 構成を追加すると、問題は解決します。
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <依存関係> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId > <バージョン>3.1.0</version> <scope>提供</scope> </dependency>