metadata.messages_ja.xml Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of findsecbugs-plugin Show documentation
Show all versions of findsecbugs-plugin Show documentation
Core module of the project. It include all the FindBugs detectors.
The resulting jar is the published plugin.
<?xml version="1.0" encoding="UTF-8"?> <MessageCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://findsecbugs.h3xstream.com/messagecollection.xsd"> <Plugin> <ShortDescription>Find Security Bugs</ShortDescription> <Details>Find Security Bugs は,セキュリティ監査の支援を目的としたプラグインです。</Details> <BugsUrl>http://h3xstream.github.io/find-sec-bugs/bugs_ja.htm</BugsUrl> <AllBugsUrl>http://h3xstream.github.io/find-sec-bugs/bugs_ja.htm</AllBugsUrl> </Plugin> <!-- Predictable Pseudo Random Generator (PRG) --> <Detector class="com.h3xstream.findsecbugs.PredictableRandomDetector"> <Details>予測可能な擬似乱数生成器 (PRG:Pseudo Random Generator) の使用を検出します。 </Details> </Detector> <BugPattern type="PREDICTABLE_RANDOM"> <ShortDescription>予測可能な擬似乱数生成器</ShortDescription> <LongDescription>{3} の使用は予測可能です。</LongDescription> <Details> <![CDATA[ <p>セキュリティが重要であるコンテキストで,予測可能な乱数が使用されると脆弱性につながることがあります。たとえば,その乱数が次のように使用されたときです。</p> <ul> <li>CSRF トークン:予測可能なトークンは CSRF 攻撃につながり,攻撃者はトークンの価値を知ることになります</li> <li>パスワードリセットトークン(電子メールで送信):予測可能なパスワードトークンは,アカウントの奪取につながる可能性があります。これは,攻撃者がパスワード変更フォームのURLを推測するためです</li> <li>その他の秘密の値</li> </ul> <p> 手っ取り早い解決策は <b>java.util.Random</b> の使用を <b>java.security.SecureRandom</b> などのより強固なものに置き換えてください。 </p> <p> <b>脆弱なコード:</b><br> <pre>String generateSecretToken() { Random r = new Random(); return Long.toHexString(r.nextLong()); }</pre> </p> <p> <b>解決策:</b> <pre>import org.apache.commons.codec.binary.Hex; String generateSecretToken() { SecureRandom secRandom = new SecureRandom(); byte[] result = new byte[32]; secRandom.nextBytes(result); return Hex.encodeHexString(result); }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html">Cracking Random Number Generators - Part 1 (http://jazzy.id.au)</a><br> <a href="https://www.securecoding.cert.org/confluence/display/java/MSC02-J.+Generate+strong+random+numbers">CERT: MSC02-J. Generate strong random numbers</a><br> <a href="http://cwe.mitre.org/data/definitions/330.html">CWE-330: Use of Insufficiently Random Values</a><br> <a href="http://blog.h3xstream.com/2014/12/predicting-struts-csrf-token-cve-2014.html">Predicting Struts CSRF Token (Example of real-life vulnerability and exploitation)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECPR">予測可能な擬似乱数生成器</BugCode> <BugPattern type="PREDICTABLE_RANDOM_SCALA"> <ShortDescription>予測可能な擬似乱数生成器 (Scala)</ShortDescription> <LongDescription>{3} の使用は予測可能です。</LongDescription> <Details> <![CDATA[ <p>セキュリティが重要であるコンテキストで,予測可能な乱数が使用されると脆弱性につながることがあります。たとえば,その乱数が次のように使用されたときです。</p> <ul> <li>CSRF トークン:予測可能なトークンは CSRF 攻撃につながり,攻撃者はトークンの価値を知ることになります</li> <li>パスワードリセットトークン(電子メールで送信):予測可能なパスワードトークンは,アカウントの奪取につながる可能性があります。これは,攻撃者がパスワード変更フォームのURLを推測するためです</li> <li>その他の秘密の値</li> </ul> <p> 手っ取り早い解決策は <b>java.util.Random</b> の使用を <b>java.security.SecureRandom</b> などのより強固なものに置き換えてください。 </p> <p> <b>脆弱なコード:</b><br> <pre>import scala.util.Random def generateSecretToken() { val result = Seq.fill(16)(Random.nextInt) return result.map("%02x" format _).mkString }</pre> </p> <p> <b>解決策:</b> <pre>import java.security.SecureRandom def generateSecretToken() { val rand = new SecureRandom() val value = Array.ofDim[Byte](16) rand.nextBytes(value) return value.map("%02x" format _).mkString }</pre> </p> <!--<p> <b>解決策:</b> <pre>import java.security.SecureRandom import scala.util.Random._ def generateSecretToken() { val secRandom = javaRandomToRandom(new SecureRandom()) val result = Seq.fill(16)(secRandom.nextInt) return result.map("%02x" format _).mkString }</pre> </p>--> <br> <p> <b>参考文献</b><br> <a href="http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html">Cracking Random Number Generators - Part 1 (http://jazzy.id.au)</a><br> <a href="https://www.securecoding.cert.org/confluence/display/java/MSC02-J.+Generate+strong+random+numbers">CERT: MSC02-J. Generate strong random numbers</a><br> <a href="http://cwe.mitre.org/data/definitions/330.html">CWE-330: Use of Insufficiently Random Values</a><br> <a href="http://blog.h3xstream.com/2014/12/predicting-struts-csrf-token-cve-2014.html">Predicting Struts CSRF Token (Example of real-life vulnerability and exploitation)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECPRS">予測可能な擬似乱数生成器 (Scala)</BugCode> <!-- Servlet parameter --> <Detector class="com.h3xstream.findsecbugs.endpoint.ServletEndpointDetector"> <Details>ServletRequest と HttpServletRequest からのフィルターされていない値を特定します。</Details> </Detector> <BugPattern type="SERVLET_PARAMETER"> <ShortDescription>信頼できないサーブレットパラメーター</ShortDescription> <LongDescription>メソッド {3} は,クライアントによって操作されている String 型の値を返します。</LongDescription> <Details> <![CDATA[ <p>サーブレットは,さまざまなメソッドから GET と POST のパラメーターを読むことができます。取得した値は安全でないと考えるべきです。 次のようなセンシティブな API に渡す前に,それらの値を検証したりエスケープする必要があるかもしれません。</p> <ul> <li>SQL クエリー (SQL インジェクションにつながる可能性)</li> <li>ファイルオープン (パストラバーサルにつながる可能性)</li> <li>コマンド実行 (潜在的なコマンドインジェクション)</li> <li>HTMLの組み立て (潜在的な XSS)</li> <li>など...</li> </ul> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSP">サーブレットパラメーター</BugCode> <BugPattern type="SERVLET_CONTENT_TYPE"> <ShortDescription>信頼できない Content-Type ヘッダー</ShortDescription> <LongDescription>HTTP ヘッダー Content-Type はクライアントによって操作可能です。</LongDescription> <Details> <![CDATA[ <p> HTTP ヘッダー Content-Type は,クライアントによって操作可能です。したがって,その値をセキュリティ上重要な決定では使用しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/807.html">CWE-807: Untrusted Inputs in a Security Decision</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSCT">Content-Type ヘッダー</BugCode> <BugPattern type="SERVLET_SERVER_NAME"> <ShortDescription>信頼できない Host ヘッダー</ShortDescription> <LongDescription>受信されるホスト名は,多くの場合,クライアントによって操作が可能です。</LongDescription> <Details> <![CDATA[ <p>Host ヘッダーは,クライアントによって操作可能です。したがって,その値をセキュリティ上重要な決定では使用しないでください。 <code>ServletRequest.getServerName()</code> と <code>HttpServletRequest.getHeader("Host")</code> は,どちらも <code>Host</code> ヘッダーを抽出するという同じ動作をします。</p> <pre> GET /testpage HTTP/1.1 Host: www.example.com [...]</pre> <p> アプリケーションにサービスを提供するウェブコンテナは,デフォルトでは,アプリケーションにリクエストをリダイレクトすることがあります。 これにより,悪意のあるユーザーが Host ヘッダーで任意の値を配置できるようになります。 リクエストに関して行うセキュリティ上の決定において,この値を信頼しないことをお勧めします。 </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/807.html">CWE-807: Untrusted Inputs in a Security Decision</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSSN">Host ヘッダー</BugCode> <BugPattern type="SERVLET_SESSION_ID"> <ShortDescription>信頼できないセッションクッキーの値</ShortDescription> <LongDescription>セッション ID への直接アクセスは避けるべきです。</LongDescription> <Details> <![CDATA[ <p> メソッド <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getRequestedSessionId()"><code>HttpServletRequest.getRequestedSessionId()</code></a> は, 通常,クッキー <code>JSESSIONID</code> の値を返します。この値は通常,セッション管理ロジックと正常でない開発者コードだけがアクセスします。 </p> <p> クライアントに渡される値は一般的に英数字の値です (例えば <code>JSESSIONID=jp6q31lq2myn</code>)。しかし,この値はクライアントによって改ざんできます。 次の HTTP リクエストは変更の可能性を示しています。 <pre> GET /somePage HTTP/1.1 Host: yourwebsite.com User-Agent: Mozilla/5.0 Cookie: JSESSIONID=Any value of the user's choice!!??'''"> </pre> </p> <p>そのため,JSESSIONID は,その値が既存のセッション ID と一致するかどうかを確認するためだけに使用されるべきです。 そうでない場合,そのユーザーは認証されていないユーザーであると考えるべきです。加えて,セッション ID の値をログに記録してはいけません。 その場合,ログファイルには有効なアクティブセッション ID を含むことができ,ID がログに記録されかつアクティブなままであるすべてのセッションを内部者がハイジャックすることを許してしまいます。 </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Session_Management_Cheat_Sheet">OWASP: Session Management Cheat Sheet</a><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSSID">セッションクッキーの値</BugCode> <BugPattern type="SERVLET_QUERY_STRING"> <ShortDescription>信頼できないクエリー文字列</ShortDescription> <LongDescription>クエリー文字列は任意の値を指定できます。</LongDescription> <Details> <![CDATA[ <p>クエリー文字列は,GET パラメーターの名前と値を連結したものです。意図したパラメーター以外を渡すことができます。</p> <p>URL リクエストが <code>/app/servlet.htm?a=1&b=2</code> のときは,クエリー文字列を抜き出すと <code>a=1&b=2</code> になります。</p> <p><code>HttpServletRequest.getParameter()</code> のようなメソッドで取得した個々のパラメーター値と同じように,<code>HttpServletRequest.getQueryString()</code> から取得した値は安全でないと見なすべきです。 センシティブな API に渡す前に,クエリー文字列から取得したものを検証またはエスケープする必要があります。 </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSSQ">クエリー文字列</BugCode> <BugPattern type="SERVLET_HEADER"> <ShortDescription>信頼できない HTTP ヘッダー</ShortDescription> <LongDescription>リクエストヘッダーはクライアントによって容易に改ざんできます。</LongDescription> <Details> <![CDATA[ <p>リクエストヘッダーはリクエストしているユーザーによって容易に改ざんできます。 一般的には,ブラウザーから攻撃者による変更がないリクエストが来ることを仮定すべきではありません。 このように,リクエストに関して行うあらゆるセキュリティ上の決定において,その値を信頼しないでください。</p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/807.html">CWE-807: Untrusted Inputs in a Security Decision</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSH">信頼できない HTTP ヘッダー</BugCode> <BugPattern type="SERVLET_HEADER_REFERER"> <ShortDescription>信頼できない Referer ヘッダー</ShortDescription> <LongDescription>ヘッダー "Referer" はクライアントによって容易に偽装できます。</LongDescription> <Details> <![CDATA[ <p> 動作: <ul> <li>リクエストが悪意のあるユーザーから来ているなら,任意の値をこのヘッダーに割り当てられます。</li> <li>リクエストが安全 (https) である別のオリジンから開始されたときは,"Referer" は存在しません。</li> </ul> </p> <p> 推奨: <ul> <li>このヘッダーの値に基づいてアクセス制御を行うべきではありません。</li> <li>CSRF 保護は,この値にだけ基づいて行われるべきではありません (<a href="http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#z14">オプションなので</a>)。</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/807.html">CWE-807: Untrusted Inputs in a Security Decision</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSHR">Referer ヘッダー</BugCode> <BugPattern type="SERVLET_HEADER_USER_AGENT"> <ShortDescription>信頼できない User-Agent ヘッダー</ShortDescription> <LongDescription>ヘッダー "User-Agent" は,クライアントによって容易に偽装できます。</LongDescription> <Details> <![CDATA[ <p>ヘッダー "User-Agent" は,クライアントによって容易に偽装できます。User-Agent に基づいて (クローラー UA に対して) 異なった動作をすることは推奨できません。</p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/807.html">CWE-807: Untrusted Inputs in a Security Decision</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSHUA">User-Agent ヘッダー</BugCode> <!-- Cookie usage --> <Detector class="com.h3xstream.findsecbugs.cookie.CookieReadDetector"> <Details>直接的なクッキーの使用を特定します。</Details> </Detector> <BugPattern type="COOKIE_USAGE"> <ShortDescription>クッキー内に機密データの可能性</ShortDescription> <LongDescription>アプリケーションによって機密データがクッキーに格納されている可能性があります。</LongDescription> <Details> <![CDATA[ <p>カスタムクッキーに格納する情報は,機密やセッションに関連してはいけません。ほとんどの場合,機密データはセッションだけに格納して,ユーザーのセッションクッキーによってだけ参照されるべきです。 HttpSession (HttpServletRequest.getSession()) を参照してください。</p> <p>カスタムクッキーは,特定のセッションから独立した,より長く存続する必要がある情報のために使用できます。</p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/315.html">CWE-315: Cleartext Storage of Sensitive Information in a Cookie</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCU">クッキー内に機密データの可能性</BugCode> <!-- Path traversal --> <Detector class="com.h3xstream.findsecbugs.file.PathTraversalDetector"> <Details>パスをパラメーターとして受け取るファイルシステムアクセス要求を特定します。</Details> </Detector> <BugPattern type="PATH_TRAVERSAL_IN"> <ShortDescription>潜在的なパストラバーサル (ファイル読み出し)</ShortDescription> <LongDescription>メソッド {3} は,ユーザー入力によって指定された場所のファイルを読み出します。</LongDescription> <Details> <![CDATA[ <p>内容を読むためにファイルが開かれています。ファイル名は <b>入力</b> パラメーターに由来しています。 フィルターされていないパラメーターがこのファイル API に渡されると,ファイルシステムの任意の場所からファイルを読み出せるかもしれません。</p> <p>このルールは <b>潜在的な</b> パストラバーサルの脆弱性を特定します。多くの場合,構築されたファイルパスはユーザーが制御できません。 その場合,報告された事例は誤検出です。</p> <br> <p> <b>脆弱なコード:</b><br> <pre>@GET @Path("/images/{image}") @Produces("images/*") public Response getImage(@javax.ws.rs.PathParam("image") String image) { File file = new File("resources/images/", image); //Weak point if (!file.exists()) { return Response.status(Status.NOT_FOUND).build(); } return Response.ok().entity(new FileInputStream(file)).build(); }</pre> </p> <br> <p> <b>解決策:</b><br> <pre>import org.apache.commons.io.FilenameUtils; @GET @Path("/images/{image}") @Produces("images/*") public Response getImage(@javax.ws.rs.PathParam("image") String image) { File file = new File("resources/images/", FilenameUtils.getName(image)); //Fix if (!file.exists()) { return Response.status(Status.NOT_FOUND).build(); } return Response.ok().entity(new FileInputStream(file)).build(); }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246952/Path%20Traversal">WASC: Path Traversal</a><br> <a href="https://www.owasp.org/index.php/Path_Traversal">OWASP: Path Traversal</a><br> <a href="http://capec.mitre.org/data/definitions/126.html">CAPEC-126: Path Traversal</a><br> <a href="http://cwe.mitre.org/data/definitions/22.html">CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECPTI">潜在的なパストラバーサル (ファイル読み出し)</BugCode> <BugPattern type="PATH_TRAVERSAL_OUT"> <ShortDescription>潜在的なパストラバーサル (ファイル書き込み)</ShortDescription> <LongDescription>メソッド {3} は,ユーザー入力によって指定された場所のファイルに書き込みます。</LongDescription> <Details> <![CDATA[ <p>内容を書くためにファイルが開かれています。ファイル名は <b>入力</b> パラメーターに由来しています。 フィルターされていないパラメーターがこのファイル API に渡されると,ファイルシステムの任意の場所からファイルを変更できるかもしれません。</p> <p>このルールは <b>潜在的な</b> パストラバーサルの脆弱性を特定します。多くの場合,構築されたファイルパスはユーザーが制御できません。 その場合,報告された事例は誤検出です。</p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246952/Path%20Traversal">WASC-33: Path Traversal</a><br> <a href="https://www.owasp.org/index.php/Path_Traversal">OWASP: Path Traversal</a><br> <a href="http://capec.mitre.org/data/definitions/126.html">CAPEC-126: Path Traversal</a><br> <a href="http://cwe.mitre.org/data/definitions/22.html">CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECPTO">潜在的なパストラバーサル (ファイル書き込み)</BugCode> <!-- Path traversal with a Scala-specific code sample --> <BugPattern type="SCALA_PATH_TRAVERSAL_IN"> <ShortDescription>潜在的なパストラバーサル (ファイル読み出し)</ShortDescription> <LongDescription>メソッド {3} は,ユーザー入力によって指定された場所のファイルを読み出します。</LongDescription> <Details> <![CDATA[ <p>内容を読むためにファイルが開かれています。ファイル名は <b>入力</b> パラメーターに由来しています。 フィルターされていないパラメーターがこのファイル API に渡されると,ファイルシステムの任意の場所からファイルを読み出せるかもしれません。</p> <p>このルールは <b>潜在的な</b> パストラバーサルの脆弱性を特定します。多くの場合,構築されたファイルパスはユーザーが制御できません。 その場合,報告された事例は誤検出です。</p> <br> <p> <b>脆弱なコード:</b><br> <pre>def getWordList(value:String) = Action { if (!Files.exists(Paths.get("public/lists/" + value))) { NotFound("File not found") } else { val result = Source.fromFile("public/lists/" + value).getLines().mkString // Weak point Ok(result) } }</pre> </p> <br> <p> <b>解決策:</b><br> <pre>import org.apache.commons.io.FilenameUtils; def getWordList(value:String) = Action { val filename = "public/lists/" + FilenameUtils.getName(value) if (!Files.exists(Paths.get(filename))) { NotFound("File not found") } else { val result = Source.fromFile(filename).getLines().mkString // Fix Ok(result) } }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246952/Path%20Traversal">WASC: Path Traversal</a><br> <a href="https://www.owasp.org/index.php/Path_Traversal">OWASP: Path Traversal</a><br> <a href="http://capec.mitre.org/data/definitions/126.html">CAPEC-126: Path Traversal</a><br> <a href="http://cwe.mitre.org/data/definitions/22.html">CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SSECPTI">潜在的なパストラバーサル (ファイル読み出し)</BugCode> <!-- Command injection --> <Detector class="com.h3xstream.findsecbugs.injection.command.CommandInjectionDetector"> <Details>コマンドインジェクションの発生源を特定します。</Details> </Detector> <BugPattern type="COMMAND_INJECTION"> <ShortDescription>潜在的なコマンドインジェクション</ShortDescription> <LongDescription>{3} の使用は,コマンドインジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p>強調表示された API は,システムコマンドを実行するために使用されています。 フィルタリングされていない入力がこの API に渡されると,任意のコマンド実行につながる可能性があります。</p> <br> <p> <b>脆弱なコード:</b><br> <pre>import java.lang.Runtime; Runtime r = Runtime.getRuntime(); r.exec("/bin/sh -c some_tool" + input);</pre> </p> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Command_Injection">OWASP: Command Injection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/78.html">CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCI">コマンドインジェクション</BugCode> <BugPattern type="SCALA_COMMAND_INJECTION"> <ShortDescription>潜在的なコマンドインジェクション (Scala)</ShortDescription> <LongDescription>コマンド実行は,インジェクションに対して脆弱になる可能性があります。</LongDescription> <Details> <![CDATA[ <p>強調表示された API は,システムコマンドを実行するために使用されています。 フィルタリングされていない入力がこの API に渡されると,任意のコマンド実行につながる可能性があります。</p> <br> <p> <b>脆弱なコード:</b><br> <pre>def executeCommand(value:String) = Action { val result = value.! Ok("Result:\n"+result) }</pre> </p> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Command_Injection">OWASP: Command Injection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/78.html">CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSCI">コマンドインジェクション (Scala)</BugCode> <!-- Weak FilenameUtils method --> <Detector class="com.h3xstream.findsecbugs.WeakFilenameUtilsMethodDetector"> <Details>FilenameUtils のいくつかのメソッドの使用を特定します。</Details> </Detector> <BugPattern type="WEAK_FILENAMEUTILS"> <ShortDescription>FilenameUtils は NULL バイトをフィルタリングしない</ShortDescription> <LongDescription>FilenameUtils.{3} は,NULL バイトをフィルタリングしません。</LongDescription> <Details> <![CDATA[ <p><code>FilenameUtils</code> のいくつかのメソッドは NULL バイト (<code>0x00</code>) をフィルターしません。</p> <p>NULL バイトがファイル名に挿入され,そのファイル名が OS に渡されると取得されるファイルは NULL バイトより前に指定されたファイル名になります。 OS レベルであるので,たとえ Java 自体が NULLl バイトを気にしたり特別扱いをしなくても,すべての文字列が NULL バイトで終了するためです。 この OS の動作は,ファイル名の検証を「ファイル名の末尾 (たとえば,末尾が ".log" であるか) を調べ,アクセスしても安全なファイルであるかを確認」といった具合にしていると回避されてしまうことがあります。</p> <p>これを修正するためには,次の2つのことが推奨されています:</p> <ul> <li>Java 7 update 40 以降,または Java 8 以上へのアップグレード <a href="http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8014846">NNULL バイトインジェクションはそれらのバージョンで修正されています</a>。</li> <li>信頼できないユーザーによって与えられた任意のファイル名が有効であることを確認するため,入念に検証します (すなわち,null が含まれていないか,パス文字が加えられていないか,など)。</li> </ul> <p>NULL バイトインジェクションの影響を受けない最新版の Java を使用していることがわかっているなら,このルールを無効にできます。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246949/Null%20Byte%20Injection">WASC-28: Null Byte Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/158.html">CWE-158: Improper Neutralization of Null Byte or NUL Character</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWF">FilenameUtils が NULL バイトをフィルタリングしない</BugCode> <!-- Weak TrustManager --> <Detector class="com.h3xstream.findsecbugs.crypto.WeakTrustManagerDetector"> <Details>弱い TrustManager 実装を特定します。</Details> </Detector> <!-- SSL Disabler --> <Detector class="com.h3xstream.findsecbugs.scala.SslDisablerDetector"> <Details>"SSL Disabler" の使用を特定します。</Details> </Detector> <BugPattern type="WEAK_TRUST_MANAGER"> <ShortDescription>任意の証明書を受け入れる TrustManager</ShortDescription> <LongDescription>任意の証明書を受け入れる TrustManager は,通信が中間者攻撃に対して脆弱になります。</LongDescription> <Details> <![CDATA[ <p>空の <code>TrustManager</code> 実装は,多くの場合, ルート <a href="http://en.wikipedia.org/wiki/Certificate_authority">認証局</a> によって署名されていないホストに簡単に接続するために使用されます。 結果として,クライアントがどの証明書も信頼してしまうので, これは <a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">中間者攻撃 (Man-in-the-middle attacks)</a> に対して脆弱です。 </p> <p> (たとえば,truststore に基づいて) 特定の証明書を許可する TrustManager を構築すべきです。 適切な実装の詳細については: <a href="http://stackoverflow.com/a/6378872/89769">[1]</a> <a href="http://stackoverflow.com/a/5493452/89769">[2]</a> </p> <br> <p> <b>脆弱なコード:</b><br> <pre>class TrustAllManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { //Trust any client connecting (no certificate validation) } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { //Trust any remote server (no certificate validation) } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }</pre> </p> <br> <p> <b>解決策 (キーストアに基づく TrustMangager):</b><br> <pre>KeyStore ks = //Load keystore containing the certificates trusted SSLContext sc = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null); </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246945/Insufficient%20Transport%20Layer%20Protection">WASC-04: Insufficient Transport Layer Protection</a><br> <a href="http://cwe.mitre.org/data/definitions/295.html">CWE-295: Improper Certificate Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWTM">弱い TrustManager 実装</BugCode> <BugPattern type="WEAK_HOSTNAME_VERIFIER"> <ShortDescription>任意の署名付き証明書を受け入れる HostnameVerifier</ShortDescription> <LongDescription>任意の署名付き証明書を受け入れる HostnameVerifier は,通信が中間者攻撃に対して脆弱になります。</LongDescription> <Details> <![CDATA[ <p>任意のホストを受け入れる <code>HostnameVerifier</code> は,多くのホストで証明書を再利用するためによく使用されます。 結果として,クライアントがどの証明書も信頼してしまうので,これは <a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">中間者攻撃 (Man-in-the-middle attacks)</a> に対して脆弱です。 </p> <p> (たとえば,truststore に基づいて) 特定の証明書を許可する TrustManager を構築すべきです。 複数のサブドメインで再利用するためのワイルドカード証明書を作成すべきです。 適切な実装の詳細については: <a href="http://stackoverflow.com/a/6378872/89769">[1]</a> <a href="http://stackoverflow.com/a/5493452/89769">[2]</a> </p> <br> <p> <b>脆弱なコード:</b><br> <pre>public class AllHosts implements HostnameVerifier { public boolean verify(final String hostname, final SSLSession session) { return true; } }</pre> </p> <br> <p> <b>解決策 (キーストアに基づく TrustMangager):</b><br> <pre>KeyStore ks = //Load keystore containing the certificates trusted SSLContext sc = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null); </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246945/Insufficient%20Transport%20Layer%20Protection">WASC-04: Insufficient Transport Layer Protection</a><br> <a href="http://cwe.mitre.org/data/definitions/295.html">CWE-295: Improper Certificate Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWHV">弱い TrustManager 実装</BugCode> <!-- JAXWS --> <Detector class="com.h3xstream.findsecbugs.endpoint.JaxWsEndpointDetector"> <Details>JAX-WS API を実装している Web サービスのエンドポイントを特定します。</Details> </Detector> <BugPattern type="JAXWS_ENDPOINT"> <ShortDescription>JAX-WS SOAP エンドポイントを発見</ShortDescription> <LongDescription>{0}.{1} は SOAP Web サービスのエンドポイントです。</LongDescription> <Details> <![CDATA[ <p>このメソッドは,SOAP Web サービス (JSR224) の一部です。</p> <p> <b>この Web サービスの安全性を分析する必要があります。たとえば:</b> <ul> <li>認証を強制したときはテストすべきです。</li> <li>アクセス制御を強制したときはテストすべきです。</li> <li>潜在的な脆弱性のために入力を追跡すべきです。</li> <li>通信は理想的には SSL の上で行うべきです。</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Web_Service_Security_Cheat_Sheet">OWASP: Web Service Security Cheat Sheet</a><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECJWS">JAX-WS SOAP エンドポイント</BugCode> <!-- JAXRS --> <Detector class="com.h3xstream.findsecbugs.endpoint.JaxRsEndpointDetector"> <Details>JAX-RS API を実装している Web サービスのエンドポイントを特定します。</Details> </Detector> <BugPattern type="JAXRS_ENDPOINT"> <ShortDescription>JAX-RS REST エンドポイントを発見</ShortDescription> <LongDescription>{0}.{1} は REST Web サービスのエンドポイントです。</LongDescription> <Details> <![CDATA[ <p>このメソッドは REST Web サービス (JSR311) の一部です。</p> <p> <b>この Web サービスの安全性を分析する必要があります。たとえば:</b> <ul> <li>認証を強制したときはテストすべきです。</li> <li>アクセス制御を強制したときはテストすべきです。</li> <li>潜在的な脆弱性のために入力を追跡すべきです。</li> <li>通信は理想的には SSL の上で行うべきです。</li> <li>サービスが書き込み (POSTなど) をサポートしているときは,CSRF に対する脆弱性を調査すべきです。</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/REST_Assessment_Cheat_Sheet">OWASP: REST Assessment Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/REST_Security_Cheat_Sheet">OWASP: REST Security Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Web_Service_Security_Cheat_Sheet">OWASP: Web Service Security Cheat Sheet</a><br> 1. <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)">OWASP: Cross-Site Request Forgery</a><br> <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet">OWASP: CSRF Prevention Cheat Sheet</a><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECJRS">JAX-RS REST エンドポイント</BugCode> <!-- Tapestry --> <Detector class="com.h3xstream.findsecbugs.endpoint.TapestryEndpointDetector"> <Details>ユーザー入力を受け入れる Tapestry "Pages" を特定します。</Details> </Detector> <BugPattern type="TAPESTRY_ENDPOINT"> <ShortDescription>Tapestry ページを発見</ShortDescription> <LongDescription>{0} は Tapestry ページです。</LongDescription> <Details> <![CDATA[ <p>アプリケーション起動時に Tapestry エンドポイントが検出されました。 Tapestry アプリケーションは,各ページのバッキング Java クラスと対応する Tapestry マークアップ言語ページ (.tml ファイル) で構成されます。 リクエストが受信されると,GET/POST パラメーターはバッキング Java クラス内の特定の入力にマッピングされます。 マッピングはいずれかで行われます。<br>フィールド名で:</p> <pre><code> [...] protected String input; [...] </code></pre> <p>または,明示的なアノテーションの定義で: </p> <pre><code> [...] @org.apache.tapestry5.annotations.Parameter protected String parameter1; @org.apache.tapestry5.annotations.Component(id = "password") private PasswordField passwordField; [...] </code></pre> <p>ページは,ビュー <code>[/resources/package/PageName].tml</code> にマッピングされます。</p> <p>このアプリケーションの各 Tapestry ページは,このように自動的にマッピングされるすべての入力が使用される前に適切に検証されているか調査すべきです。</p> <br> <p> <b>参考文献</b><br> <a href="http://tapestry.apache.org/">Apache Tapestry Home Page</a><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECTE">Tapestry ページ</BugCode> <!-- Wicket --> <Detector class="com.h3xstream.findsecbugs.endpoint.WicketEndpointDetector"> <Details>入力として機能する Wicket "WebPages" を特定します。</Details> </Detector> <BugPattern type="WICKET_ENDPOINT"> <ShortDescription>Wicket ページを発見</ShortDescription> <LongDescription>{0} は Wicket WebPage です。</LongDescription> <Details> <![CDATA[ <p>このクラスは,Wicket の WebPage を表します。入力はコンストラクターに渡された <code>PageParameters</code> インスタンスから自動的に読み出されます。 現在のページは, ビュー [/package/WebPageName].html にマッピングされます。</p> <p>このアプリケーションの各 Wicket ページは,このように自動的にマッピングされるすべての入力を使用される前に適切に検証されているか調査すべきです。</p> <br> <p> <b>参考文献</b><br> <a href="https://wicket.apache.org/">Apache Wicket Home Page</a><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWE">Wicket ページ</BugCode> <!-- Weak Message Digest MD5 and SHA1 --> <Detector class="com.h3xstream.findsecbugs.crypto.WeakMessageDigestDetector"> <Details>置き換え可能な弱い暗号化ハッシュ関数の使用を特定します。</Details> </Detector> <BugPattern type="WEAK_MESSAGE_DIGEST_MD5"> <ShortDescription>MD2,MD4,MD5 は弱いハッシュ関数</ShortDescription> <LongDescription>{3} は推奨される暗号化ハッシュ関数ではありません。</LongDescription> <Details> <![CDATA[ <p>アルゴリズム MD2,MD4,MD5 は推奨されているメッセージダイジェストではありません。 <b>PBKDF2 (Password-Based Key Derivation Function 2)</b> は,たとえばパスワードをハッシュ化するために使用すべきです。</p> <blockquote> 「MD5 ハッシュ関数のセキュリティは深刻に損なわれています。 2.6 GHz Pentium 4 プロセッサー (複雑さは 2<sup>24.1</sup>) のコンピューターで数秒で衝突を見つけられる衝突攻撃が存在します。[1] さらに,既製のコンピューティングハードウェア (複雑さは 2<sup>39</sup>) を使用して,数時間以内に指定されたプレフィックスを持つ2つの入力の衝突を生成する選択プリフィックス衝突攻撃もあります。[2]」<br> - <a href="https://en.wikipedia.org/wiki/MD5#Security">Wikipedia: MD5 - Security</a> </blockquote> <blockquote> 「<b>SHA-224,SHA-256,SHA-384,SHA-512,SHA-512/224,SHA-512/256</b>:<br> これらのハッシュ関数の使用は,すべてのハッシュ関数アプリケーションで許容されています。」<br> - <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths p.15</a> </blockquote> <blockquote> 「PBKDF (Password-Based Key Derivation Function) の主な考え方は,各パスワードをテストするために必要な時間を増やすことによって,パスワードに対する辞書攻撃またはブルートフォース攻撃を遅延させることです。 もっともらしいパスワードのリストを持つ攻撃者は,既知の反復カウンタと salt を使用して PBKDF を評価できます。 攻撃者は試行ごとにかなりの計算時間を費やさなければならないので,辞書攻撃やブルートフォース攻撃を適用するのが難しくなります。」<br> - <a href="http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf">NIST: Recommendation for Password-Based Key Derivation p.12</a> </blockquote> <br> <p> <b>脆弱なコード:</b><br> <pre>MessageDigest md5Digest = MessageDigest.getInstance("MD5"); md5Digest.update(password.getBytes()); byte[] hashValue = md5Digest.digest();</pre> <br> <pre>byte[] hashValue = DigestUtils.getMd5Digest().digest(password.getBytes());</pre> </p> <br> <p> <b>解決策 (Bouncy Castle を使う):</b><br> <pre>public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(password.getBytes("UTF-8"), salt.getBytes(), 4096); return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); }</pre> <br> <b>解決策 (Java 8 以降):</b><br> <pre>public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 4096, 256 * 8); SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); return f.generateSecret(spec).getEncoded(); }</pre> </p> <br> <p> <b>参考文献</b><br> [1] <a href="http://www.win.tue.nl/hashclash/On%20Collisions%20for%20MD5%20-%20M.M.J.%20Stevens.pdf">On Collisions for MD5</a>: Master Thesis by M.M.J. Stevens<br> [2] <a href="http://homepages.cwi.nl/~stevens/papers/stJOC%20-%20Chosen-Prefix%20Collisions%20for%20MD5%20and%20Applications.pdf">Chosen-prefix collisions for MD5 and applications</a>: Paper written by Marc Stevens<br> <a href="https://en.wikipedia.org/wiki/MD5">Wikipedia: MD5</a><br> <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths</a><br> <a href="http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf">NIST: Recommendation for Password-Based Key Derivation</a><br> <a href="http://stackoverflow.com/questions/22580853/reliable-implementation-of-pbkdf2-hmac-sha256-for-java">Stackoverflow: Reliable implementation of PBKDF2-HMAC-SHA256 for Java</a><br> <a href="http://cwe.mitre.org/data/definitions/327.html">CWE-327: Use of a Broken or Risky Cryptographic Algorithm</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECMD5">MD2,MD4,MD5 は弱いハッシュ関数</BugCode> <BugPattern type="WEAK_MESSAGE_DIGEST_SHA1"> <ShortDescription>SHA-1 は弱いハッシュ関数</ShortDescription> <LongDescription>{3} は推奨される暗号ハッシュ関数ではありません。</LongDescription> <Details> <![CDATA[ <p>アルゴリズム SHA-1 は,ハッシュパスワード,署名検証などのために推奨されるアルゴリズムではありません。 <b>PBKDF2 (Password-Based Key Derivation Function 2)</b> は,たとえばパスワードをハッシュ化するために使用すべきです。</p> <blockquote> 「<b>デジタル署名生成用の SHA-1:</b><br> SHA-1は,NIST プロトコル仕様ガイダンスで特に許可されているデジタル署名の生成にだけ使用できます。 他のすべてのアプリケーションでは,<u>SHA-1 をデジタル署名の生成に使用してはいけません</u>。<br> <b>デジタル署名検証用の SHA-1:</b><br> デジタル署名検証では,<u>SHA-1 は従来の使用が許可されています</u>。<br> [...]<br> <b>SHA-224,SHA-256,SHA-384,SHA-512,SHA-512/224,SHA-512/256</b>:<br> これらのハッシュ関数の使用は,すべてのハッシュ関数アプリケーションで許容されています。」<br> - <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths p.15</a> </blockquote> <blockquote> 「PBKDF (Password-Based Key Derivation Function) の主な考え方は,各パスワードをテストするために必要な時間を増やすことによって,パスワードに対する辞書攻撃またはブルートフォース攻撃を遅延させることです。 もっともらしいパスワードのリストを持つ攻撃者は,既知の反復カウンタと salt を使用して PBKDF を評価できます。 攻撃者は試行ごとにかなりの計算時間を費やさなければならないので,辞書攻撃やブルートフォース攻撃を適用するのが難しくなります。」<br> - <a href="http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf">NIST: Recommendation for Password-Based Key Derivation p.12</a> </blockquote> <br> <p> <b>脆弱なコード:</b><br> <pre>MessageDigest sha1Digest = MessageDigest.getInstance("SHA1"); sha1Digest.update(password.getBytes()); byte[] hashValue = sha1Digest.digest();</pre> <br> <pre>byte[] hashValue = DigestUtils.getSha1Digest().digest(password.getBytes());</pre> </p> <br> <p> <b>解決策 (Bouncy Castle を使う):</b><br> <pre>public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(password.getBytes("UTF-8"), salt.getBytes(), 4096); return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); }</pre> <br> <b>解決策 (Java 8 以降):</b><br> <pre>public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 4096, 256 * 8); SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); return f.generateSecret(spec).getEncoded(); }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://community.qualys.com/blogs/securitylabs/2014/09/09/sha1-deprecation-what-you-need-to-know">Qualys blog: SHA1 Deprecation: What You Need to Know</a><br> <a href="https://googleonlinesecurity.blogspot.ca/2014/09/gradually-sunsetting-sha-1.html">Google Online Security Blog: Gradually sunsetting SHA-1</a><br> <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths</a><br> <a href="http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf">NIST: Recommendation for Password-Based Key Derivation</a><br> <a href="http://stackoverflow.com/questions/22580853/reliable-implementation-of-pbkdf2-hmac-sha256-for-java">Stackoverflow: Reliable implementation of PBKDF2-HMAC-SHA256 for Java</a><br> <a href="http://cwe.mitre.org/data/definitions/327.html">CWE-327: Use of a Broken or Risky Cryptographic Algorithm</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSHA1">SHA-1 は弱いハッシュ関数</BugCode> <!-- Weak SSL/TLS protocols --> <Detector class="com.h3xstream.findsecbugs.crypto.WeakTLSDetector"> <Details>弱い SSL/TLS プロトコルの使用を特定します。</Details> </Detector> <BugPattern type="DEFAULT_HTTP_CLIENT"> <ShortDescription>デフォルトのコンストラクターを持つ DefaultHttpClient は TLS 1.2 と互換性がない</ShortDescription> <LongDescription>デフォルトのコンストラクターを持つ DefaultHttpClient は TLS 1.2 と互換性がありません。</LongDescription> <Details> <![CDATA[ <p> <b>脆弱なコード:</b><br> <pre> HttpClient client = new DefaultHttpClient(); </pre> </p> <p> <p><b>解決策:</b><br> 推奨構成の1つを使用して,https.protocols JVM オプションを TLSv1.2 を含むように設定して,実装を改良します:</p> <p> <ul> <li>代わりに <a href="http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/SystemDefaultHttpClient.html">SystemDefaultHttpClient</a> を使用します。</li> <p> <b>サンプルコード:</b><br> <pre> HttpClient client = new SystemDefaultHttpClient(); </pre> </p> <li>SSLSocketFactory に基づいて HttpClient を作成します - <a href="https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html#getSystemSocketFactory()">getSystemSocketFactory()</a> で SSLSocketFactory のインスタンスを取得して,HttpClient の作成に使用します。</li> <li>SSLConnectionSocketFactory に基づいて HttpClient を作成する - <a href="https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLConnectionSocketFactory.html#getSystemSocketFactory()">getSystemSocketFactory()</a> でインスタンスを取得して,HttpClient の作成に使用します。</li> <li>HttpClientBuilder を使用します - build() を呼び出す前に <a href="http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/HttpClientBuilder.html#useSystemProperties()">useSystemProperties()</a> を呼び出します。</li> <p> <b>サンプルコード:</b><br> <pre> HttpClient client = HttpClientBuilder.create().useSystemProperties().build(); </pre> </p> <li>HttpClients - <a href="https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/HttpClients.html#createSystem()">createSystem()</a> を呼び出してインスタンスを作成します。</li> <p> <b>サンプルコード:</b><br> <pre> HttpClient client = HttpClients.createSystem(); </pre> </p> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https">Diagnosing TLS, SSL, and HTTPS</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHTTPCLIENT">DefaultHttpClient</BugCode> <BugPattern type="SSL_CONTEXT"> <ShortDescription>弱い SSLContext</ShortDescription> <LongDescription>SSLContext は TLS 1.2 と互換性がある必要があります。</LongDescription> <Details> <![CDATA[ <p> <b>脆弱なコード:</b><br> <pre> SSLContext.getInstance("SSL"); </pre> </p> <p> <p><b>解決策:</b><br> https.protocols JVM オプションを TLSv1.2を含むように設定して,実装を改良します:</p> <pre> SSLContext.getInstance("TLS"); </pre> <p> </p> <br> <p> <b>参考文献</b><br> <a href="https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https">Diagnosing TLS, SSL, and HTTPS</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSSL">SSLContext</BugCode> <!-- Custom Message Digest --> <Detector class="com.h3xstream.findsecbugs.crypto.CustomMessageDigestDetector"> <Details>メッセージダイジェスト/ハッシュアルゴリズムの独自実装を特定します。</Details> </Detector> <BugPattern type="CUSTOM_MESSAGE_DIGEST"> <ShortDescription>メッセージダイジェストが独自</ShortDescription> <LongDescription>{0} は独自暗号化ハッシュ関数の実装です。</LongDescription> <Details> <![CDATA[ <p>独自メッセージダイジェストの実装は間違いの元になりやすいです</p> <p><a href="http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html">NIST</a> は,SHA-224,SHA-256,SHA-384,SHA-512,SHA-512/224,SHA-512/256 の使用を推奨しています。</p> <blockquote> 「<b>デジタル署名生成用の SHA-1:</b><br> SHA-1は,NIST プロトコル仕様ガイダンスで特に許可されているデジタル署名の生成にだけ使用できます。 他のすべてのアプリケーションでは,<u>SHA-1 をデジタル署名の生成に使用してはいけません</u>。<br> <b>デジタル署名検証用の SHA-1:</b><br> デジタル署名検証では,<u>SHA-1 は従来の使用が許可されています</u>。<br> [...]<br> <b>SHA-224,SHA-256,SHA-384,SHA-512,SHA-512/224,SHA-512/256</b>:<br> これらのハッシュ関数の使用は,すべてのハッシュ関数アプリケーションで許容されています。」<br> - <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths p.15</a> </blockquote> <p> <b>脆弱なコード:</b><br> <pre>MyProprietaryMessageDigest extends MessageDigest { @Override protected byte[] engineDigest() { [...] // 独創性は悪い考え return [...]; } }</pre> </p> <p> <p>承認されたアルゴリズムの1つを使用するように実装を改良します。セキュリティニーズを満たす十分に強いアルゴリズムを使用します。</p> <p> <b>解決例:</b><br> <pre>MessageDigest sha256Digest = MessageDigest.getInstance("SHA256"); sha256Digest.update(password.getBytes());</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html">NIST Approved Hashing Algorithms</a><br> <a href="http://cwe.mitre.org/data/definitions/327.html">CWE-327: Use of a Broken or Risky Cryptographic Algorithm</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCMD">メッセージダイジェストが独自</BugCode> <!-- FileUpload Filename --> <Detector class="com.h3xstream.findsecbugs.file.FileUploadFilenameDetector"> <Details>ファイルアップロード API によって与えられたファイル名は,クライアントによって改ざんされる可能性があります。</Details> </Detector> <BugPattern type="FILE_UPLOAD_FILENAME"> <ShortDescription>汚染されたファイル名の読み取り</ShortDescription> <LongDescription>読み取られたファイル名は,クライアントによって改ざんされている可能性があります。</LongDescription> <Details> <![CDATA[ <p>ファイルアップロード API によって与えられたファイル名は,権限のないファイルを参照するためにクライアントによって改ざんされる可能性があります。</p> <p>たとえば:</p> <ul> <li><code>"../../../config/overide_file"</code></li> <li><code>"shell.jsp\u0000expected.gif"</code></li> </ul> <p>したがって,そのような値を直接ファイルシステム API に渡すべきではありません。可能であれば,アプリケーションは独自のファイル名を生成して使用すべきです。 そうでなければ与えられたファイル名を「不正なパス文字 (たとえば/ \) が含まれていない」や「許可されたファイルを参照している」というように,正しく構成されているか検証すべきです。</p> <br> <p> <b>参考文献</b><br> <a href="http://blogs.securiteam.com/index.php/archives/1268">Securiteam: File upload security recommendations</a><br> <a href="http://cwe.mitre.org/data/definitions/22.html">CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')</a><br> <a href="http://projects.webappsec.org/w/page/13246952/Path%20Traversal">WASC-33: Path Traversal</a><br> <a href="https://www.owasp.org/index.php/Path_Traversal">OWASP: Path Traversal</a><br> <a href="http://capec.mitre.org/data/definitions/126.html">CAPEC-126: Path Traversal</a><br> <a href="http://cwe.mitre.org/data/definitions/22.html">CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECFUN">汚染されたファイル名の読み取り</BugCode> <!-- ReDOS --> <Detector class="com.h3xstream.findsecbugs.ReDosDetector"> <Details>正規表現は,入力によって指数関数的に増加することがあります。</Details> </Detector> <BugPattern type="REDOS"> <ShortDescription>正規表現による DoS (ReDoS)</ShortDescription> <LongDescription>正規表現 "{0}" は,サービス拒否攻撃 (ReDoS) に対して脆弱です。</LongDescription> <Details> <![CDATA[ <p> 正規表現 (regexs) は,DoS攻撃 (ReDoS と呼ばれる) の対象となることがよくあります。 これは,正規表現がどのように定義されているかに応じて,正規表現エンジンが特定の文字列を解析するときに長い時間がかかることが原因です。 <p> たとえば, 次の正規表現の場合: <b>^(a+)+$</b>,"<code>aaaaaaaaaaaaaaaaX</code>" を入力すると正規表現エンジンは 65536 通りの異なるパスを解析します。 <sup>[1] OWASP リファレンスから抜粋した例</sup></p> <p> したがって,1回のリクエストでサーバー側で大量の計算が発生する可能性があります。 この正規表現 (およびその他同様のもの) に関連する問題は,括弧の内側にある + (または *) と括弧の外側にある + (または *) によって,同じ入力文字を2つの異なる方法で受け入れられるということです。 この書き方は,どちらの + でも文字 'a' を消費します。これを修正するためには,曖昧さを取り除くために正規表現を書き直す必要があります。 例えば,<b>^a+$</b> のようにたやすく書き直すことができます。それは,おそらく作者の意図していることです (a がいくつあっても)。 これが元の正規表現を意図しているなら,この新しい正規表現はすぐに評価されるので,ReDoS の対象とはなりません。 </p> <br> <p> <b>参考文献</b><br> <a href="http://www.jroller.com/sebastianKuebeck/entry/detecting_and_preventing_redos_vulnerabilities">Sebastian Kubeck's Weblog: Detecting and Preventing ReDoS Vulnerabilities</a><br> <sup>[1]</sup> <a href="https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS">OWASP: Regular expression Denial of Service</a><br> <a href="http://cwe.mitre.org/data/definitions/400.html">CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECRD">正規表現による DoS</BugCode> <!-- XMLStreamReader XXE --> <Detector class="com.h3xstream.findsecbugs.xml.XmlStreamReaderDetector"> <Details>XML 外部エンティティ (XXE:XML External Entities) 攻撃に脆弱な XMLStreamReader の使用を特定します。</Details> </Detector> <BugPattern type="XXE_XMLSTREAMREADER"> <ShortDescription>XXE に脆弱な XML 解析 (XMLStreamReader)</ShortDescription> <LongDescription>XML 解析は,XXE 攻撃に対して脆弱です。</LongDescription> <Details> <![CDATA[ <!--XXE_GENERIC_START--> <h3>攻撃</h3> <p>信頼されていないソースから受け取った XML を処理しているときに,XML パーサーが XML エンティティをサポートしていると XML 外部エンティティ (XXE:XML External Entities) 攻撃が発生する可能性があります。</p> <p><b>リスク 1: ローカルファイルの内容の暴露 (XXE: <u>X</u>ML e<u>X</u>ternal <u>E</u>ntity)</b></p> <p> <pre> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <foo>&xxe;</foo></pre> </p> <b>リスク 2: サービス拒否 (XEE: <u>X</u>ml <u>E</u>ntity <u>E</u>xpansion)</b> <p> <pre> <?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> [...] <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz></pre> </p> <h3>解決策</h3> <p> XML パーサーの危険な機能が公開されないようにするためには,コードを次のように変更します。 </p> <!--XXE_GENERIC_END--> <p><b>脆弱なコード:</b></p> <p> <pre>public void parseXML(InputStream input) throws XMLStreamException { XMLInputFactory factory = XMLInputFactory.newFactory(); XMLStreamReader reader = factory.createXMLStreamReader(input); [...] }</pre> </p> <br> <p> 次のスニペットでは,利用可能な2つの解決策を示しています。1つまはた両方のプロパティーを設定できます。 </p> <p><b>外部エンティティーを無効にする解決策:</b></p> <p> <pre>public void parseXML(InputStream input) throws XMLStreamException { XMLInputFactory factory = XMLInputFactory.newFactory(); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); XMLStreamReader reader = factory.createXMLStreamReader(input); [...] }</pre> </p> <p><b>DTD を無効にする解決策:</b></p> <p> <pre>public void parseXML(InputStream input) throws XMLStreamException { XMLInputFactory factory = XMLInputFactory.newFactory(); factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); XMLStreamReader reader = factory.createXMLStreamReader(input); [...] }</pre> </p> <br> <p> <b>参考文献</b><br> <!--XXE_GENERIC_START--> <a href="http://cwe.mitre.org/data/definitions/611.html">CWE-611: Improper Restriction of XML External Entity Reference ('XXE')</a><br> <a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=61702260">CERT: IDS10-J. Prevent XML external entity attacks</a><br> <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">OWASP.org: XML External Entity (XXE) Processing</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Expansion">WS-Attacks.org: XML Entity Expansion</a><br> <a href="http://www.ws-attacks.org/index.php/XML_External_Entity_DOS">WS-Attacks.org: XML External Entity DOS</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Reference_Attack">WS-Attacks.org: XML Entity Reference Attack</a><br> <a href="http://blog.h3xstream.com/2014/06/identifying-xml-external-entity.html">Identifying Xml eXternal Entity vulnerability (XXE)</a><br> <!--XXE_GENERIC_END--> <a href="http://openjdk.java.net/jeps/185">JEP 185: Restrict Fetching of External XML Resources</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXXESTR">XMLStreamReader を使用した XXE 脆弱性</BugCode> <!-- SAXParser XXE --> <Detector class="com.h3xstream.findsecbugs.xml.XxeDetector"> <Details>XML 外部エンティティ (XXE:XML External Entities) 攻撃に脆弱な XML パーサーの使用を特定します。</Details> </Detector> <BugPattern type="XXE_SAXPARSER"> <ShortDescription>XXE に脆弱な XML 解析 (SAXParser)</ShortDescription> <LongDescription>{3} の使用は,XXE 攻撃に対して脆弱です。</LongDescription> <Details> <![CDATA[ <!--XXE_GENERIC_START--> <h3>攻撃</h3> <p>信頼されていないソースから受け取った XML を処理しているときに,XML パーサーが XML エンティティをサポートしていると XML 外部エンティティ (XXE:XML External Entities) 攻撃が発生する可能性があります。</p> <p><b>リスク 1: ローカルファイルの内容の暴露 (XXE: <u>X</u>ML e<u>X</u>ternal <u>E</u>ntity)</b></p> <p> <pre> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <foo>&xxe;</foo></pre> </p> <b>リスク 2: サービス拒否 (XEE: <u>X</u>ml <u>E</u>ntity <u>E</u>xpansion)</b> <p> <pre> <?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> [...] <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz></pre> </p> <h3>解決策</h3> <p> XML パーサーの危険な機能が公開されないようにするためには,コードを次のように変更します。 </p> <!--XXE_GENERIC_END--> <p><b>脆弱なコード:</b></p> <p> <pre> SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(inputStream, customHandler);</pre> </p> <br> <p> 次のスニペットでは,利用可能な2つの解決策を示しています。1つまはた両方のプロパティーを設定できます。 </p> <p><b>"Secure processing" モードを使用した解決策:</b></p> <p> この設定により,サービス拒否攻撃とリモートファイルアクセスから保護されます。 <pre> SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); SAXParser parser = spf.newSAXParser(); parser.parse(inputStream, customHandler);</pre> </p> <p><b>DTD を無効にする解決策:</b></p> <p> DTD を無効にすることによって,ほとんどすべての XXE 攻撃 が防止されます。 <pre> SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); SAXParser parser = spf.newSAXParser(); parser.parse(inputStream, customHandler);</pre> </p> <br> <p> <b>参考文献</b><br> <!--XXE_GENERIC_START--> <a href="http://cwe.mitre.org/data/definitions/611.html">CWE-611: Improper Restriction of XML External Entity Reference ('XXE')</a><br> <a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=61702260">CERT: IDS10-J. Prevent XML external entity attacks</a><br> <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">OWASP.org: XML External Entity (XXE) Processing</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Expansion">WS-Attacks.org: XML Entity Expansion</a><br> <a href="http://www.ws-attacks.org/index.php/XML_External_Entity_DOS">WS-Attacks.org: XML External Entity DOS</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Reference_Attack">WS-Attacks.org: XML Entity Reference Attack</a><br> <a href="http://blog.h3xstream.com/2014/06/identifying-xml-external-entity.html">Identifying Xml eXternal Entity vulnerability (XXE)</a><br> <!--XXE_GENERIC_END--> <a href="http://xerces.apache.org/xerces-j/features.html">Xerces complete features list</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXXESAX">SAXParser を使用した XXE の脆弱性</BugCode> <BugPattern type="XXE_XMLREADER"> <ShortDescription>XXE に脆弱な XML 解析 (XMLReader)</ShortDescription> <LongDescription>{3} の使用は,XXE 攻撃に対して脆弱です。</LongDescription> <Details> <![CDATA[ <!--XXE_GENERIC_START--> <h3>攻撃</h3> <p>信頼されていないソースから受け取った XML を処理しているときに,XML パーサーが XML エンティティをサポートしていると XML 外部エンティティ (XXE:XML External Entities) 攻撃が発生する可能性があります。</p> <p><b>リスク 1: ローカルファイルの内容の暴露 (XXE: <u>X</u>ML e<u>X</u>ternal <u>E</u>ntity)</b></p> <p> <pre> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <foo>&xxe;</foo></pre> </p> <b>リスク 2: サービス拒否 (XEE: <u>X</u>ml <u>E</u>ntity <u>E</u>xpansion)</b> <p> <pre> <?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> [...] <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz></pre> </p> <h3>Solution</h3> <p> XML パーサーの危険な機能が公開されないようにするためには,コードを次のように変更します。 </p> <!--XXE_GENERIC_END--> <p><b>脆弱なコード:</b></p> <p> <pre> XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(customHandler); reader.parse(new InputSource(inputStream));</pre> </p> <br> <p> 次のスニペットでは,利用可能な2つの解決策を示しています。1つまはた両方のプロパティーを設定できます。 </p> <p><b>"Secure processing" モードを使用した解決策:</b></p> <p> この設定により,サービス拒否攻撃とリモートファイルアクセスから保護されます。 <pre> XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); reader.setContentHandler(customHandler); reader.parse(new InputSource(inputStream));</pre> </p> <p><b>DTD を無効にする解決策:</b></p> <p> DTD を無効にすることによって,ほとんどすべての XXE 攻撃 が防止されます。 <pre> XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); reader.setContentHandler(customHandler); reader.parse(new InputSource(inputStream));</pre> </p> <br> <p> <b>参考文献</b><br> <!--XXE_GENERIC_START--> <a href="http://cwe.mitre.org/data/definitions/611.html">CWE-611: Improper Restriction of XML External Entity Reference ('XXE')</a><br> <a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=61702260">CERT: IDS10-J. Prevent XML external entity attacks</a><br> <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">OWASP.org: XML External Entity (XXE) Processing</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Expansion">WS-Attacks.org: XML Entity Expansion</a><br> <a href="http://www.ws-attacks.org/index.php/XML_External_Entity_DOS">WS-Attacks.org: XML External Entity DOS</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Reference_Attack">WS-Attacks.org: XML Entity Reference Attack</a><br> <a href="http://blog.h3xstream.com/2014/06/identifying-xml-external-entity.html">Identifying Xml eXternal Entity vulnerability (XXE)</a><br> <!--XXE_GENERIC_END--> <a href="http://xerces.apache.org/xerces-j/features.html">Xerces complete features list</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXXEREAD">XMLReader を使用した XXE の脆弱性</BugCode> <BugPattern type="XXE_DOCUMENT"> <ShortDescription>XXE に脆弱な XML 解析 (DocumentBuilder)</ShortDescription> <LongDescription>{3} の使用は,XXE 攻撃に対して脆弱です。</LongDescription> <Details> <![CDATA[ <!--XXE_GENERIC_START--> <h3>攻撃</h3> <p>信頼されていないソースから受け取った XML を処理しているときに,XML パーサーが XML エンティティをサポートしていると XML 外部エンティティ (XXE:XML External Entities) 攻撃が発生する可能性があります。</p> <p><b>リスク 1: ローカルファイルの内容の暴露 (XXE: <u>X</u>ML e<u>X</u>ternal <u>E</u>ntity)</b></p> <p> <pre> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <foo>&xxe;</foo></pre> </p> <b>リスク 2: サービス拒否 (XEE: <u>X</u>ml <u>E</u>ntity <u>E</u>xpansion)</b> <p> <pre> <?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> [...] <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz></pre> </p> <h3>Solution</h3> <p> XML パーサーの危険な機能が公開されないようにするためには,コードを次のように変更します。 </p> <!--XXE_GENERIC_END--> <p><b>脆弱なコード:</b></p> <p> <pre> DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = db.parse(input);</pre> </p> <br> <p> 次のスニペットでは,利用可能な2つの解決策を示しています。1つまはた両方のプロパティーを設定できます。 </p> <p><b>"Secure processing" モードを使用した解決策:</b></p> <p> この設定により,サービス拒否攻撃とリモートファイルアクセスから保護されます。 <pre> DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(input);</pre> </p> <p><b>DTD を無効にする解決策:</b></p> <p> DTD を無効にすることによって,ほとんどすべての XXE 攻撃 が防止されます。 <pre> DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(input);</pre> </p> <br> <p> <b>参考文献</b><br> <!--XXE_GENERIC_START--> <a href="http://cwe.mitre.org/data/definitions/611.html">CWE-611: Improper Restriction of XML External Entity Reference ('XXE')</a><br> <a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=61702260">CERT: IDS10-J. Prevent XML external entity attacks</a><br> <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">OWASP.org: XML External Entity (XXE) Processing</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Expansion">WS-Attacks.org: XML Entity Expansion</a><br> <a href="http://www.ws-attacks.org/index.php/XML_External_Entity_DOS">WS-Attacks.org: XML External Entity DOS</a><br> <a href="http://www.ws-attacks.org/index.php/XML_Entity_Reference_Attack">WS-Attacks.org: XML Entity Reference Attack</a><br> <a href="http://blog.h3xstream.com/2014/06/identifying-xml-external-entity.html">Identifying Xml eXternal Entity vulnerability (XXE)</a><br> <!--XXE_GENERIC_END--> <a href="http://xerces.apache.org/xerces2-j/features.html">Xerces2 complete features list</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXXEDOC">DocumentBuilder を使用した XXE の脆弱性</BugCode> <!-- XPath Injection for Javax --> <Detector class="com.h3xstream.findsecbugs.xpath.XPathInjectionDetector"> <Details>汚染された入力を使用する XPath クエリを発見します。</Details> </Detector> <BugPattern type="XPATH_INJECTION"> <ShortDescription>潜在的な XPath インジェクション</ShortDescription> <LongDescription>{3} の使用は,XPath インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> XPath インジェクションのリスクは,SQL インジェクションに似ています。XPath クエリーに信頼できないユーザー入力が含まれていると,完全なデータソースが暴露される可能性があります。 これにより,攻撃者は権限のないデータにアクセスしたり,標的の XML を悪意をもって改ざんする可能性があります。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-39: XPath Injection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/643.html">CWE-643: Improper Neutralization of Data within XPath Expressions ('XPath Injection')</a><br> <a href="https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=61407250">CERT: IDS09-J. Prevent XPath Injection (archive)</a><br> <a href="http://media.blackhat.com/bh-eu-12/Siddharth/bh-eu-12-Siddharth-Xpath-WP.pdf">Black Hat Europe 2012: Hacking XPath 2.0</a><br> <a href="http://www.balisage.net/Proceedings/vol7/html/Vlist02/BalisageVol7-Vlist02.html">Balisage: XQuery Injection</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXPI">XPath インジェクション</BugCode> <!-- Struts1 --> <Detector class="com.h3xstream.findsecbugs.endpoint.Struts1EndpointDetector"> <Details>Struts 1 のエンドポイント (アクションとも呼ばれます) を特定します。</Details> </Detector> <BugPattern type="STRUTS1_ENDPOINT"> <ShortDescription>Struts 1 アクション を発見</ShortDescription> <LongDescription>{0} は Struts 1 のエンドポイント (アクション) です。</LongDescription> <Details> <![CDATA[ <p>このクラスは Struts 1 のアクションです。</p> <p>リクエストがこのコントローラーにルーティングされると,HTTP パラメーター を含む Form オブジェクトが自動的にインスタンス化されます。 これらのパラメーターが安全に使用されているかを確認するためにレビューすべきです。</p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSTR1">Struts 1 アクション</BugCode> <!-- Struts2 --> <Detector class="com.h3xstream.findsecbugs.endpoint.Struts2EndpointDetector"> <Details>Struts 2 のエンドポイントを特定します。</Details> </Detector> <BugPattern type="STRUTS2_ENDPOINT"> <ShortDescription>Struts 2 のエンドポイントを発見</ShortDescription> <LongDescription>{0} は Struts 2 のエンドポイントです。</LongDescription> <Details> <![CDATA[ <p>Struts 2 では,エンドポイントは Plain Old Java Object (POJO) です。つまり,インターフェース/クラスを実装/継承する必要がないということです。</p> <p>リクエストがそのコントローラー (選択されたクラス) にルーティングされると与えられた HTTP パラメーターが自動的にクラスのセッターにマッピングされます。 そのため,フォームにそれらの値が含まれていなくても,このクラスのすべてのセッターは信頼できない入力として見なすべきです。 オブジェクトにそのようなセッターがあるかぎり,攻撃者はリクエストに追加の値を与えるだけで,オブジェクトに設定できます。 これらのパラメーターが安全に使用されているかを確認するためにレビューすべきです。</p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSTR2">Struts 2 エンドポイント</BugCode> <!-- Spring Controller --> <Detector class="com.h3xstream.findsecbugs.endpoint.SpringMvcEndpointDetector"> <Details>Spring のエンドポイント (コントローラーとも呼ばれます) を特定します。</Details> </Detector> <BugPattern type="SPRING_ENDPOINT"> <ShortDescription>Spring のエンドポイントを発見</ShortDescription> <LongDescription>{0} は Spring のエンドポイント (コントローラー) です。</LongDescription> <Details> <![CDATA[ <p>このクラスは Spring コントローラーです。 <code>RequestMapping</code> (そのショートカットアノテーション <code>GetMapping</code>,<code>PostMapping</code>,<code>PutMapping</code>, <code>DeleteMapping</code>,<code>PatchMapping</code>) というアノテーションが付けられたすべてのメソッドは,リモートから到達可能です。 リモートに公開したメソッドが潜在的な攻撃者に公開しても安全であるかを確認するために,このクラスを分析する必要があります。</p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSC">Spring エンドポイント</BugCode> <!-- Spring CSRF Protection Disabled --> <Detector class="com.h3xstream.findsecbugs.csrf.SpringCsrfProtectionDisabledDetector"> <Details>Spring CSRF 保護の無効化を検出します。</Details> </Detector> <BugPattern type="SPRING_CSRF_PROTECTION_DISABLED"> <ShortDescription>Spring CSRF 保護の無効化</ShortDescription> <LongDescription>Spring Security の CSRF 保護を無効にすることは,標準の Web アプリケーションでは安全ではありません。</LongDescription> <Details> <![CDATA[ <p>Spring Security の CSRF 保護を無効にすることは,標準の Web アプリケーションでは安全ではありません。</p> <p>この保護を無効にすることが有効なユースケースは,ブラウザ以外のクライアントによってだけ使用されることが保証されている状態変更操作を公開するサービスです。</p> <p> <b>安全でない設定:</b><br> <pre>@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }</pre> </p> <p> <b>参考文献</b><br> <a href="https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#when-to-use-csrf-protection">Spring Security Official Documentation: When to use CSRF protection</a><br> <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29">OWASP: Cross-Site Request Forgery</a><br> <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet">OWASP: CSRF Prevention Cheat Sheet</a><br> <a href="https://cwe.mitre.org/data/definitions/352.html">CWE-352: Cross-Site Request Forgery (CSRF)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSPRCSRFPD">Spring CSRF 保護の無効化</BugCode> <!-- Spring CSRF Unrestricted RequestMapping --> <Detector class="com.h3xstream.findsecbugs.csrf.SpringCsrfUnrestrictedRequestMappingDetector"> <Details>Spring で制限のない RequestMapping による CSRF を検出します。</Details> </Detector> <BugPattern type="SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING"> <ShortDescription>Spring の制限のない RequestMapping による CSRF</ShortDescription> <LongDescription>Spring の制限のない RequestMapping は,このメソッドを CSRF 攻撃 に対して脆弱にします。</LongDescription> <Details> <![CDATA[ <p><code>RequestMapping</code> というアノテーションが付けられたメソッドは,デフォルトですべての HTTP リクエストメソッドにマッピングされます。 しかし,Spring Security の CSRF 保護は HTTP リクエストメソッド <code>GET</code>,<code>HEAD</code>,<code>TRACE</code>,<code>OPTIONS</code> に対して有効になっていません (トークンが漏洩する可能性があるため)。 したがって,<code>RequestMapping</code> でアノテーションされ,マッピングを絞り込まない状態変更メソッド <code>POST</code>,<code>PUT</code>,<code>DELETE</code>,<code>PATCH</code> は CSRF 攻撃に対して脆弱です。</p> <p> <b>脆弱なコード:</b><br> <pre>@Controller public class UnsafeController { @RequestMapping("/path") public void writeData() { // State-changing operations performed within this method. } }</pre> </p> <p> <b>解決策 (Spring Framework 4.3 以降):</b><br> <pre>@Controller public class SafeController { /** * For methods without side-effects use @GetMapping. */ @GetMapping("/path") public String readData() { // No state-changing operations performed within this method. return ""; } /** * For state-changing methods use either @PostMapping, @PutMapping, @DeleteMapping, or @PatchMapping. */ @PostMapping("/path") public void writeData() { // State-changing operations performed within this method. } }</pre> </p> <p> <b>解決策 (Spring Framework 4.3 以前):</b><br> <pre>@Controller public class SafeController { /** * For methods without side-effects use either * RequestMethod.GET, RequestMethod.HEAD, RequestMethod.TRACE, or RequestMethod.OPTIONS. */ @RequestMapping(value = "/path", method = RequestMethod.GET) public String readData() { // No state-changing operations performed within this method. return ""; } /** * For state-changing methods use either * RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, or RequestMethod.PATCH. */ @RequestMapping(value = "/path", method = RequestMethod.POST) public void writeData() { // State-changing operations performed within this method. } }</pre> </p> <p> <b>参考文献</b><br> <a href="https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-use-proper-verbs">Spring Security Official Documentation: Use proper HTTP verbs (CSRF protection)</a><br> <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29">OWASP: Cross-Site Request Forgery</a><br> <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet">OWASP: CSRF Prevention Cheat Sheet</a><br> <a href="https://cwe.mitre.org/data/definitions/352.html">CWE-352: Cross-Site Request Forgery (CSRF)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSPRCSRFURM">Spring の制限のない RequestMapping による CSRF</BugCode> <!-- Custom Injection --> <Detector class="com.h3xstream.findsecbugs.injection.custom.CustomInjectionDetector"> <Details>独自メソッドに対するインジェクションを発見するディテクタです。</Details> </Detector> <BugPattern type="CUSTOM_INJECTION"> <ShortDescription>潜在的インジェクション (独自)</ShortDescription> <LongDescription>{3} の使用は,インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> 特定されたメソッドはインジェクションの影響を受けやすいです。入力を検証して,適切にエスケープする必要があります。 </p> <p> <b>脆弱なコード:</b><br> <pre>SqlUtil.execQuery("select * from UserEntity t where id = " + parameterInput);</pre> </p> <p> <a href="https://github.com/find-sec-bugs/find-sec-bugs/wiki/Custom-signatures">カスタムシグネチャを設定する方法</a> の詳細については,オンラインウィキを参照してください。 </p> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCUSTOMI">インジェクション (独自)</BugCode> <!-- SQL Injection --> <Detector class="com.h3xstream.findsecbugs.injection.sql.SqlInjectionDetector"> <Details>文字列を受け入れる SQL API (Hibernate,JPA,JDO) におけるさまざまな種類の SQL インジェクションを特定します。</Details> </Detector> <!-- SQL Injection (Generic) --> <!-- Specialized description are below --> <BugPattern type="SQL_INJECTION"> <ShortDescription>潜在的な SQL インジェクション</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 プリペアードステートメントの代わりに,各パラメーターを手動でエスケープすることもできます。 </p> <p> <b>脆弱なコード:</b><br> <pre> createQuery("select * from User where id = '"+inputId+"'"); </pre> </p> <p> <b>解決策:</b><br> <pre> import org.owasp.esapi.Encoder; createQuery("select * from User where id = '"+Encoder.encodeForSQL(inputId)+"'"); </pre> </p> <br> <p> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLI">SQL インジェクション</BugCode> <!-- SQL Injection Turbine --> <BugPattern type="SQL_INJECTION_TURBINE"> <ShortDescription>Turbine による潜在的な SQL インジェクション</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 Turbine API は,Java コードを使用してクエリーを作成する DSL を提供します。 </p> <p> <b>脆弱なコード:</b><br> <pre> List<Record> BasePeer.executeQuery( "select * from Customer where id=" + inputId ); </pre> </p> <p> <b>解決策 (Criteria DSL を使用):</b><br> <pre> Criteria c = new Criteria(); c.add( CustomerPeer.ID, inputId ); List<Customer> customers = CustomerPeer.doSelect( c ); </pre> <b>解決策 (特殊なメソッドを使用):</b><br> <pre> Customer customer = CustomerPeer.retrieveByPK( new NumberKey( inputId ) ); </pre> <b>解決策 (OWASP Encoder を使用):</b><br> <pre> import org.owasp.esapi.Encoder; BasePeer.executeQuery("select * from Customer where id = '"+Encoder.encodeForSQL(inputId)+"'"); </pre> </p> <br> <p> <b>参考文献 (Turbine)</b><br> <a href="https://turbine.apache.org/turbine/turbine-2.1/howto/criteria-howto.html">Turbine Documentation: Criteria Howto</a><br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLITU">Turbine による SQL インジェクション</BugCode> <!-- HQL Injection --> <BugPattern type="SQL_INJECTION_HIBERNATE"> <ShortDescription>潜在的な SQL/HQL インジェクション (Hibernate)</ShortDescription> <LongDescription>{3} の使用は,SQL/HQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 プリペアードステートメントの代わりに, Hibernate Criteria を使用することもできます。 </p> <p> <b>脆弱なコード:</b><br> <pre> Session session = sessionFactory.openSession(); Query q = session.createQuery("select t from UserEntity t where id = " + input); q.execute();</pre> </p> <p> <b>解決策:</b><br> <pre> Session session = sessionFactory.openSession(); Query q = session.createQuery("select t from UserEntity t where id = :userId"); q.setString("userId",input); q.execute();</pre> </p> <p> <b>動的クエリーの解決策 (Hibernate Criteria を使用):</b><br> <pre> Session session = sessionFactory.openSession(); Query q = session.createCriteria(UserEntity.class) .add( Restrictions.like("id", input) ) .list(); q.execute();</pre> </p> <br> <p> <b>参考文献 (Hibernate)</b><br> <a href="https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html">Hibernate Documentation: Query Criteria</a><br> <a href="https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html">Hibernate Javadoc: Query Object</a><br> <a href="http://blog.h3xstream.com/2014/02/hql-for-pentesters.html">HQL for pentesters</a>: Guideline to test if the suspected code is exploitable.<br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLIHIB">HQL インジェクション</BugCode> <!-- JDOQL Injection --> <BugPattern type="SQL_INJECTION_JDO"> <ShortDescription>潜在的な SQL/JDOQL インジェクション (JDO)</ShortDescription> <LongDescription>{3} の使用は,SQL/JDOQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre> PersistenceManager pm = getPM(); Query q = pm.newQuery("select * from Users where name = " + input); q.execute();</pre> </p> <p> <b>解決策:</b><br> <pre> PersistenceManager pm = getPM(); Query q = pm.newQuery("select * from Users where name = nameParam"); q.declareParameters("String nameParam"); q.execute(input);</pre> </p> <br> <p> <b>参考文献 (JDO)</b><br> <a href="https://db.apache.org/jdo/object_retrieval.html">JDO: Object Retrieval</a><br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLIJDO">SQL インジェクション (JDO)</BugCode> <!-- JPQL Injection --> <BugPattern type="SQL_INJECTION_JPA"> <ShortDescription>潜在的な SQL/JPQL インジェクション (JPA)</ShortDescription> <LongDescription>{3} の使用は,SQL/JPQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre> EntityManager pm = getEM(); TypedQuery<UserEntity> q = em.createQuery( String.format("select * from Users where name = %s", username), UserEntity.class); UserEntity res = q.getSingleResult();</pre> </p> <p> <b>解決策:</b><br> <pre> TypedQuery<UserEntity> q = em.createQuery( "select * from Users where name = usernameParam",UserEntity.class) .setParameter("usernameParam", username); UserEntity res = q.getSingleResult();</pre> </p> <br> <p> <b>参考文献 (JPA)</b><br> <a href="http://docs.oracle.com/javaee/6/tutorial/doc/bnbrg.html">The Java EE 6 Tutorial: Creating Queries Using the Java Persistence Query Language</a><br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLIJPA">SQL インジェクション (JPA)</BugCode> <!-- SPRING JDBC Injection --> <BugPattern type="SQL_INJECTION_SPRING_JDBC"> <ShortDescription>潜在的な JDBC インジェクション (Spring JDBC)</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>JdbcTemplate jdbc = new JdbcTemplate(); int count = jdbc.queryForObject("select count(*) from Users where name = '"+paramName+"'", Integer.class); </pre> </p> <p> <b>解決策:</b><br> <pre>JdbcTemplate jdbc = new JdbcTemplate(); int count = jdbc.queryForObject("select count(*) from Users where name = ?", Integer.class, paramName);</pre> </p> <br> <b>参考文献 (Spring JDBC)</b><br> <a href="http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/jdbc.html">Spring Official Documentation: Data access with JDBC</a><br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLISPRJDBC">SQL インジェクション (Spring JDBC)</BugCode> <!-- JDBC Injection --> <BugPattern type="SQL_INJECTION_JDBC"> <ShortDescription>潜在的な JDBC インジェクション</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>Connection conn = [...]; Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("update COFFEES set SALES = "+nbSales+" where COF_NAME = '"+coffeeName+"'");</pre> </p> <p> <b>解決策:</b><br> <pre>Connection conn = [...]; conn.prepareStatement("update COFFEES set SALES = ? where COF_NAME = ?"); updateSales.setInt(1, nbSales); updateSales.setString(2, coffeeName);</pre> </p> <br> <b>参考文献 (JDBC)</b><br> <a href="http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html">Oracle Documentation: The Java Tutorials > Prepared Statements</a><br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLIJDBC">SQL インジェクション (JDBC)</BugCode> <!-- Scala Slick SQL Injection --> <BugPattern type="SCALA_SQL_INJECTION_SLICK"> <ShortDescription>潜在的な Scala Slick インジェクション</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>db.run { sql"select * from people where name = '#$value'".as[Person] }</pre> </p> <p> <b>解決策:</b><br> <pre>db.run { sql"select * from people where name = $value".as[Person] }</pre> </p> <br> <b>参考文献 (SQL インジェクション)</b></b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSSQLS">SQL インジェクション (Scala - Slick)</BugCode> <!-- Scala Anorm SQL Injection --> <BugPattern type="SCALA_SQL_INJECTION_ANORM"> <ShortDescription>潜在的な Scala Anorm インジェクション</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>val peopleParser = Macro.parser[Person]("id", "name", "age") DB.withConnection { implicit c => val people: List[Person] = SQL("select * from people where name = '" + value + "'").as(peopleParser.*) }</pre> </p> <p> <b>解決策:</b><br> <pre>val peopleParser = Macro.parser[Person]("id", "name", "age") DB.withConnection { implicit c => val people: List[Person] = SQL"select * from people where name = $value".as(peopleParser.*) }</pre> </p> <br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSSQLA">SQL インジェクション (Scala - Anorm)</BugCode> <!-- Android SQL Injection --> <Detector class="com.h3xstream.findsecbugs.injection.sql.AndroidSqlInjectionDetector"> <Details>Android API によるさまざまな種類の SQL インジェクションを特定します。</Details> </Detector> <!-- Android SQL Injection --> <BugPattern type="SQL_INJECTION_ANDROID"> <ShortDescription>潜在的な Android SQL インジェクション</ShortDescription> <LongDescription>{3} の使用は,SQL インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL クエリーに含まれる入力値は安全に渡す必要があります。プリペアードステートメントのバインド変数を使用すると SQL インジェクションのリスクを容易に軽減できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>String query = "SELECT * FROM messages WHERE uid= '"+userInput+"'" ; Cursor cursor = this.getReadableDatabase().rawQuery(query,null);</pre> </p> <p> <b>解決策:</b><br> <pre>String query = "SELECT * FROM messages WHERE uid= ?" ; Cursor cursor = this.getReadableDatabase().rawQuery(query,new String[] {userInput});</pre> </p> <br> <b>参考文献 (Android SQLite)</b><br> <a href="http://www.informit.com/articles/article.aspx?p=2268753&seqNum=5">InformIT.com: Practical Advice for Building Secure Android Databases in SQLite</a><br> <a href="https://www.packtpub.com/books/content/knowing-sql-injection-attacks-and-securing-our-android-applications-them">Packtpub.com: Knowing the SQL-injection attacks and securing our Android applications from them</a><br> <a href="https://books.google.ca/books?id=SXlMAQAAQBAJ&lpg=PR1&pg=PA64#v=onepage&q&f=false">Android Database Support (Enterprise Android: Programming Android Database Applications for the Enterprise)</a><br> <a href="https://stackoverflow.com/a/29797229/89769">Safe example of Insert, Select, Update and Delete queryies provided by Suragch</a><br> <b>参考文献 (SQL インジェクション)</b><br> <a href="http://projects.webappsec.org/w/page/13246963/SQL%20Injection">WASC-19: SQL Injection</a><br> <a href="http://capec.mitre.org/data/definitions/66.html">CAPEC-66: SQL Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/89.html">CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet">OWASP: SQL Injection Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet">OWASP: Query Parameterization Cheat Sheet</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSQLITEA">SQLite Android API の SQL インジェクション</BugCode> <!-- LDAP Injection --> <Detector class="com.h3xstream.findsecbugs.injection.ldap.LdapInjectionDetector"> <Details>JNDI API と UnboundID API のさまざまな種類の LDAP インジェクションを特定します。</Details> </Detector> <BugPattern type="LDAP_INJECTION"> <ShortDescription>潜在的な LDAP インジェクション</ShortDescription> <LongDescription> {3} の使用は,LDAP インジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> SQL と同様に,LDAP クエリーに渡されるすべての入力は安全に渡す必要があります。残念ながら,LDAP には SQL のようなプリペアードステートメントインターフェースがありません。 そのため,LDAP インジェクションに対する一次防御は,LDAP クエリーに含める前に信頼できないデータを十分に検証することです。 </p> <p> <b>リスクのあるコード:</b><br> <pre>NamingEnumeration<SearchResult> answers = context.search("dc=People,dc=example,dc=com", "(uid=" + username + ")", ctrls);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246947/LDAP%20Injection">WASC-29: LDAP Injection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A1-Injection">OWASP: Top 10 2013-A1-Injection</a><br> <a href="http://cwe.mitre.org/data/definitions/90.html">CWE-90: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection')</a><br> <a href="http://www.veracode.com/security/ldap-injection">LDAP Injection Guide: Learn How to Detect LDAP Injections and Improve LDAP Security</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECLDAPI">LDAP インジェクション</BugCode> <!-- Script Engine Code injection --> <Detector class="com.h3xstream.findsecbugs.injection.script.ScriptInjectionDetector"> <Details>さまざまな種類のコードインジェクションを特定します。</Details> </Detector> <BugPattern type="SCRIPT_ENGINE_INJECTION"> <ShortDescription>スクリプトエンジン使用時の潜在的なコードインジェクション</ShortDescription> <LongDescription>{3} の使用は,コードインジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> 動的なコードが評価されています。コードの構築を慎重に分析すべきです。悪意のあるコードの実行は,データ漏洩やオペレーティングシステムが危険にさらされる可能性があります。 ユーザーコードの評価を意図しているなら,適切なサンドボックスを用意すべきです (参考文献を参照)。 </p> <p> If the evaluation of user code is intended, a proper sandboxing should be applied (see references). </p> <p><b>リスクのあるコード:</b></p> <p> <pre> public void runCustomTrigger(String script) { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); engine.eval(script); //Bad things can happen here. }</pre> </p> <p><b>解決策:</b></p> <p> Cloudbees Rhino Sandbox ライブラリを使用した Javascript コードの安全な評価。<br> <pre> public void runCustomTrigger(String script) { SandboxContextFactory contextFactory = new SandboxContextFactory(); Context context = contextFactory.makeContext(); contextFactory.enterContext(context); try { ScriptableObject prototype = context.initStandardObjects(); prototype.setParentScope(null); Scriptable scope = context.newObject(prototype); scope.setPrototype(prototype); context.evaluateString(scope,script, null, -1, null); } finally { context.exit(); } }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://github.com/cloudbees/rhino-sandbox">Cloudbees Rhino Sandbox</a>: Utility to create sandbox with Rhino (block access to all classes)<br> <a href="http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/">CodeUtopia.net: Sandboxing Rhino in Java</a><br> <a href="http://blog.h3xstream.com/2014/11/remote-code-execution-by-design.html">Remote Code Execution .. by design</a>: 悪意のあるペイロードの例です。示したサンプルは,サンドボックスのルールをテストするために使用される可能性があります。<br> <a href="http://cwe.mitre.org/data/definitions/94.html">CWE-94: Improper Control of Generation of Code ('Code Injection')</a><br> <a href="https://cwe.mitre.org/data/definitions/95.html">CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SCRIPTE">スクリプトエンジンインジェクション</BugCode> <!-- SPEL Code injection --> <BugPattern type="SPEL_INJECTION"> <ShortDescription>SpEL 使用時の潜在的なコードインジェクション</ShortDescription> <LongDescription>{3} の使用は,コードインジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> Spring 式は,動的な値で構築されています。フィルタリングされていない値が危険なコード評価になることを避けるために値の発生源を検証すべきです。 </p> <p><b>リスクのあるコード:</b></p> <p> <pre> public void parseExpressionInterface(Person personObj,String property) { ExpressionParser parser = new SpelExpressionParser(); //Unsafe if the input is control by the user.. Expression exp = parser.parseExpression(property+" == 'Albert'"); StandardEvaluationContext testContext = new StandardEvaluationContext(personObj); boolean result = exp.getValue(testContext, Boolean.class); [...]</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/94.html">CWE-94: Improper Control of Generation of Code ('Code Injection')</a><br> <a href="http://cwe.mitre.org/data/definitions/95.html">CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')</a><br> <a href="http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html">Spring Expression Language (SpEL) - Official Documentation</a><br> <a href="https://www.mindedsecurity.com/fileshare/ExpressionLanguageInjection.pdf">Minded Security: Expression Language Injection</a><br> <a href="http://blog.h3xstream.com/2014/11/remote-code-execution-by-design.html">Remote Code Execution .. by design</a>: 悪意のあるペイロードの例です。示したサンプルは,サンドボックスのルールをテストするために使用される可能性があります。<br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SPELI">SpEL インジェクション</BugCode> <!-- EL Code injection --> <BugPattern type="EL_INJECTION"> <ShortDescription>式言語 (EL) 使用時の潜在的なコードインジェクション</ShortDescription> <LongDescription>{3} の使用は,コードインジェクションに対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> 式は動的な値で構築されています。フィルタリングされていない値が危険なコード評価になることを避けるために値の発生源を検証すべきです。 </p> <p><b>リスクのあるコード:</b></p> <p> <pre>public void evaluateExpression(String expression) { FacesContext context = FacesContext.getCurrentInstance(); ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory(); ELContext elContext = context.getELContext(); ValueExpression vex = expressionFactory.createValueExpression(elContext, expression, String.class); return (String) vex.getValue(elContext); }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://blog.mindedsecurity.com/2015/11/reliable-os-shell-with-el-expression.html">Minded Security: Abusing EL for executing OS commands</a><br> <a href="https://docs.oracle.com/javaee/6/tutorial/doc/gjddd.html">The Java EE 6 Tutorial: Expression Language</a><br> <a href="http://cwe.mitre.org/data/definitions/94.html">CWE-94: Improper Control of Generation of Code ('Code Injection')</a><br> <a href="http://cwe.mitre.org/data/definitions/95.html">CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')</a><br> <a href="https://www.mindedsecurity.com/fileshare/ExpressionLanguageInjection.pdf">Minded Security: Expression Language Injection</a><br> <a href="http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/">Dan Amodio's blog: Remote Code with Expression Language Injection</a><br> <a href="http://blog.h3xstream.com/2014/11/remote-code-execution-by-design.html">Remote Code Execution .. by design</a>: 悪意のあるペイロードの例です。示したサンプルは,サンドボックスのルールをテストするために使用される可能性があります。<br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECEL">式言語 (EL) インジェクション</BugCode> <!-- Seam Log injection --> <BugPattern type="SEAM_LOG_INJECTION"> <ShortDescription>Seam ロギング呼び出しでの潜在的なコードインジェクション</ShortDescription> <LongDescription>Seam ロギング呼び出しでの潜在的なコードインジェクション</LongDescription> <Details> <![CDATA[ <p> Seam Logging API は,ログメッセージに Bean プロパティを取り込むための式言語をサポートしています。 式言語は望まれていないコードの実行元になることもあります。 </p> <p> このコンテキストでは,式は動的な値で構築されています。フィルタリングされていない値が危険なコード評価になることを避けるために値の発生源を検証すべきです。 </p> <p><b>リスクのあるコード:</b></p> <p> <pre>public void logUser(User user) { log.info("Current logged in user : " + user.getUsername()); //... }</pre> </p> <p><b>解決策:</b></p> <p> <pre>public void logUser(User user) { log.info("Current logged in user : #0", user.getUsername()); //... }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://issues.jboss.org/browse/JBSEAM-5130">JBSEAM-5130: Issue documenting the risk</a><br> <a href="https://docs.jboss.org/seam/2.3.1.Final/reference/html_single/#d0e4185">JBoss Seam: Logging (Official documentation)</a><br> <a href="https://docs.oracle.com/javaee/6/tutorial/doc/gjddd.html">The Java EE 6 Tutorial: Expression Language</a><br> <a href="http://cwe.mitre.org/data/definitions/94.html">CWE-94: Improper Control of Generation of Code ('Code Injection')</a><br> <a href="http://cwe.mitre.org/data/definitions/95.html">CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSEAM">Expression Language (EL) Injection</BugCode> <!-- OGNL injection --> <Detector class="com.h3xstream.findsecbugs.injection.script.OgnlInjectionDetector"> <Details>OGNL インジェクションを特定します。</Details> </Detector> <BugPattern type="OGNL_INJECTION"> <ShortDescription>OGNL 式使用時の潜在的なコードインジェクション</ShortDescription> <LongDescription>OGNL 式使用時の潜在的なコードインジェクション</LongDescription> <Details> <![CDATA[ <p> 式は動的な値で構築されています。フィルタリングされていない値が危険なコード評価になることを避けるために値の発生源を検証すべきです。 </p> <p><b>リスクのあるコード:</b></p> <p> <pre> public void getUserProperty(String property) { [...] //The first argument is the dynamic expression. return ognlUtil.getValue("user."+property, ctx, root, String.class); } </pre> </p> <p><b>解決策:</b></p> <p> 一般に,OGNL 式を評価するメソッドは,ユーザー入力を受け取るべきではありません。静的構成と JSP で使用することを意図しています。 </p> <br> <p> <b>参考文献</b><br> <a href="https://community.saas.hpe.com/t5/Security-Research/Struts-2-OGNL-Expression-Injections/ba-p/288881">HP Enterprise: Struts 2 OGNL Expression Injections by Alvaro Muñoz</a><br> <a href="https://blog.gdssecurity.com/labs/2017/3/27/an-analysis-of-cve-2017-5638.html">Gotham Digital Science: An Analysis Of CVE-2017-5638</a><br> <a href="http://struts.apache.org/docs/s2-016.html">Apache Struts2: Vulnerability S2-016</a><br> <a href="https://struts.apache.org/docs/ognl.html">Apache Struts 2 Documentation: OGNL</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECOGNL">式言語 (EL) インジェクション</BugCode> <!-- HTTP Response Splitting --> <Detector class="com.h3xstream.findsecbugs.HttpResponseSplittingDetector"> <Details>HTTP レスポンス分割の弱点を検索します。</Details> </Detector> <BugPattern type="HTTP_RESPONSE_SPLITTING"> <ShortDescription>潜在的な HTTP レスポンス分割</ShortDescription> <LongDescription>{3} の使用は,HTTP ヘッダーに CRLF 文字を含めるために使用される可能性があります。</LongDescription> <Details> <![CDATA[ <p> HTTP リクエストに予期しない CR 文字と LF 文字が含まれていると,サーバーは2つの異なる HTTP レスポンス (1つではなく) として解釈される出力ストリームで応答することがあります。 攻撃者は,2番目のレスポンスを制御し,クロスサイトスクリプティングやキャッシュポイズニング攻撃などの攻撃をしかけることができます。 OWASP によると,この問題はほぼすべての今の Java EE アプリケーションサーバーで修正されていますが,入力を検証することは依然として有効です。 このリスクが懸念されるときは,問題のプラットフォームでテストして,基礎となるプラットフォームが CR または LF 文字をヘッダーに挿入できるかどうかを確認する必要があります。 この弱点は SQL インジェクションなどの優先順位よりも低いと報告されています。脆弱なプラットフォームを使用しているときは,優先度の低い警告もチェックしてください。 </p> <br> <p> <b>リスクのあるコード:</b><br> <pre>String author = request.getParameter(AUTHOR_PARAMETER); // ... Cookie cookie = new Cookie("author", author); response.addCookie(cookie);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/HTTP_Response_Splitting">OWASP: HTTP Response Splitting</a><br> <a href="http://cwe.mitre.org/data/definitions/113.html">CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')</a> <a href="http://cwe.mitre.org/data/definitions/93.html">CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHRS">HTTP レスポンス分割</BugCode> <!-- CRLF injection in logs --> <Detector class="com.h3xstream.findsecbugs.injection.crlf.CrlfLogInjectionDetector"> <Details>ログの CRLF インジェクションを検索します。</Details> </Detector> <BugPattern type="CRLF_INJECTION_LOGS"> <ShortDescription>ログの潜在的な CRLF インジェクション</ShortDescription> <LongDescription>{3} を使用すると CRLF 文字をログメッセージに含めることができます。</LongDescription> <Details> <![CDATA[ <p> 信頼できないソースからのデータがロガーに入れられ,正しく無力化されていないと,攻撃者はログエントリーを偽造したり,悪意のあるコンテンツを含めることができます。 挿入された誤ったエントリは,統計を歪めたり,管理者の気を散らしたり,悪意のある行為を委託するときに他の当事者を巻き込むために使用される可能性があります。 ログファイルが自動的に処理されていると,攻撃者はファイルの形式を破損させたり予期しない文字を挿入してファイルを使用できなくすることができます。 攻撃者は,コードやその他のコマンドをログファイルに挿入したり,ログ処理ユーティリティの脆弱性 (コマンドインジェクションや XSS など) を利用することもできます。 </p> <br> <p> <b>リスクのあるコード:</b><br> <pre>String val = request.getParameter("user"); String metadata = request.getParameter("metadata"); [...] if(authenticated) { log.info("User " + val + " (" + metadata + ") was authenticated successfully"); } else { log.info("User " + val + " (" + metadata + ") was not authenticated"); } </pre> 悪意のあるユーザーがメタデータパラメーターに値を送信する可能性があります: <code>"Firefox) was authenticated successfully\r\n[INFO] User bbb (Internet Explorer"</code>。 </p> <b>解決策:</b><br> <p> 手動で各パラメーターをエスケープします。 <pre> log.info("User " + val.replaceAll("[\r\n]","") + " (" + userAgent.replaceAll("[\r\n]","") + ") was not authenticated"); </pre> </p> <p> すべてのメッセージイベントの改行を置き換えるようにロガーサービスを設定することもできます。<a href="https://logback.qos.ch/manual/layouts.html#replace">replace 関数を使用した</a> LogBack の設定例を示します。。 <pre> <pattern>%-5level - %replace(%msg){'[\r\n]', ''}%n</pattern> </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/117.html">CWE-117: Improper Output Neutralization for Logs</a><br> <a href="http://cwe.mitre.org/data/definitions/93.html">CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')</a><br> <a href="https://logback.qos.ch/manual/layouts.html#replace">CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCRLFLOG">ログの CRLF インジェクション</BugCode> <!-- External control of system or configuration setting --> <Detector class="com.h3xstream.findsecbugs.ExternalConfigurationControlDetector"> <Details>システムまたは構成設定の外部制御を検索します。</Details> </Detector> <BugPattern type="EXTERNAL_CONFIG_CONTROL"> <ShortDescription>潜在的な構成の外部制御</ShortDescription> <LongDescription>{3} の使用は,構成を外部から制御するために使用される可能性があります。</LongDescription> <Details> <![CDATA[ <p> システム設定の外部制御を許可するとサービスが中断されたり,アプリケーションが予期せぬ悪意のある方法で動作させられたりする可能性があります。 攻撃者は,存在しないカタログ名を指定したり,データベースの権限のない部分に接続することによってエラーを引き起こす可能性があります。 </p> <br> <p> <b>リスクのあるコード:</b><br> <pre>conn.setCatalog(request.getParameter("catalog"));</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/15.html">CWE-15: External Control of System or Configuration Setting</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCONFCTRL">構成の外部制御</BugCode> <!-- Bad Hexa --> <Detector class="com.h3xstream.findsecbugs.crypto.BadHexadecimalConversionDetector"> <Details>不正な16進数の連結を特定します。</Details> </Detector> <BugPattern type="BAD_HEXA_CONVERSION"> <ShortDescription>不正な16進数の連結</ShortDescription> <LongDescription>衝突の可能性を増加させる連結で先行ゼロが省略されています。</LongDescription> <Details> <![CDATA[ <p>ハッシュ署名を含むバイト配列を人間が読める文字列に変換するとき,配列がバイト単位で読み取られると変換ミスが発生する可能性があります。 次のサンプルは,計算されたハッシュ値の各バイトから先行ゼロをトリムする <code>Integer.toHexString()</code> の使用方法を示しています。 <pre> MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] resultBytes = md.digest(password.getBytes("UTF-8")); StringBuilder stringBuilder = new StringBuilder(); for(byte b :resultBytes) { stringBuilder.append( Integer.toHexString( b & 0xFF ) ); } return stringBuilder.toString();</pre> </p> <p> この間違いは,より多くの衝突を招くので,計算されたハッシュ値を脆弱にします。 たとえば,上記の関数によってハッシュ値 "0x0679" と "0x6709" は,"679" として出力されます。 </p> <p> このような状況では,<code>toHexString()</code> を次のように <code>String.format()</code> に置き換えるべきです: <pre>stringBuilder.append( String.format( "%02X", b ) );</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/704.html">CWE-704: Incorrect Type Conversion or Cast</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECBHC">不正な16進数の連結</BugCode> <!-- Hazelcast Symmetric encryption --> <Detector class="com.h3xstream.findsecbugs.crypto.HazelcastSymmetricEncryptionDetector"> <Details>Hazelcast 対称暗号が安全でない。</Details> </Detector> <BugPattern type="HAZELCAST_SYMMETRIC_ENCRYPTION"> <ShortDescription>Hazelcast 対称暗号</ShortDescription> <LongDescription>Hazelcast のネットワーク通信は,対称暗号を使用するように構成されています。</LongDescription> <Details> <![CDATA[ <p>Hazelcast のネットワーク通信は,対称暗号 (おそらく DES または blowfish) を使用するように構成されています。</p> <p>これらの暗号だけでは,完全性や安全な認証が提供されません。非対称暗号を使用することが望ましいです。</p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246945/Insufficient%20Transport%20Layer%20Protection">WASC-04: Insufficient Transport Layer Protection</a><br> <a href="http://docs.hazelcast.org/docs/3.5/manual/html/encryption.html">Hazelcast Documentation: Encryption</a><br> <a href="http://cwe.mitre.org/data/definitions/326.html">CWE-326: Inadequate Encryption Strength</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHAZ">Hazelcast 対称暗号</BugCode> <!-- NullCipher's use --> <Detector class="com.h3xstream.findsecbugs.crypto.NullCipherDetector"> <Details>NullCipher の使用を特定します。</Details> </Detector> <BugPattern type="NULL_CIPHER"> <ShortDescription>NullCipher は安全でない</ShortDescription> <LongDescription>通常,NullCipher の使用は望ましくありません。</LongDescription> <Details> <![CDATA[ <p> <code>NullCipher</code> は,本番アプリケーションで意図的に使用されることはほとんどありません。<code>NullCipher</code> は,与えられた平文と同じ暗号文を返すように <code>Cipher</code> インターフェースを実装しています。 テストなどのいくつかのコンテキストでは,<code>NullCipher</code> が適切なときがあります。 </p> <p> <b>脆弱なコード:</b><br> <pre>Cipher doNothingCihper = new NullCipher(); [...] //The ciphertext produced will be identical to the plaintext. byte[] cipherText = c.doFinal(plainText);</pre> </p> <p> <b>解決策:</b><br> <code>NullCipher</code> を使用しないでください。不慮の使用は重大な機密性リスクを招く可能性があります。 </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/327.html">CWE-327: Use of a Broken or Risky Cryptographic Algorithm</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECNC">NullCipher</BugCode> <!-- Unencrypted Socket encryption --> <Detector class="com.h3xstream.findsecbugs.crypto.UnencryptedSocketDetector"> <Details>暗号化されていないソケット</Details> </Detector> <BugPattern type="UNENCRYPTED_SOCKET"> <ShortDescription>暗号化されていないソケット</ShortDescription> <LongDescription>{0} への暗号化されていないソケット (SSLSocket の代わりに)</LongDescription> <Details> <![CDATA[ <p> 使用される通信チャネルは暗号化されていません。攻撃者がネットワークトラフィックを傍受して,トラフィックが読み取られる可能性があります。 </p> <p> <b>脆弱なコード:</b><br> プレーンソケット (平文通信): <pre>Socket soc = new Socket("www.google.com",80);</pre> </p> <p> <b>解決策:</b><br> SSL ソケット (安全な通信): <pre>Socket soc = SSLSocketFactory.getDefault().createSocket("www.google.com", 443);</pre> </p> <p>SSL ソケットを使用する以外に,<code>SSLSocketFactory</code> を使用して,中間者攻撃の対象にならないように,すべての適切な証明書検証チェックを実行する必要があります。 チェックを正しく行う方法の詳細については,OWASP Transport Layer Protection Cheat Sheet をお読みください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Top_10_2010-A9">OWASP: Top 10 2010-A9-Insufficient Transport Layer Protection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure">OWASP: Top 10 2013-A6-Sensitive Data Exposure</a><br> <a href="https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet">OWASP: Transport Layer Protection Cheat Sheet</a><br> <a href="http://projects.webappsec.org/w/page/13246945/Insufficient%20Transport%20Layer%20Protection">WASC-04: Insufficient Transport Layer Protection</a><br> <a href="http://cwe.mitre.org/data/definitions/319.html">CWE-319: Cleartext Transmission of Sensitive Information</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECUS">暗号化されていないソケット</BugCode> <!-- Unencrypted Server Socket encryption --> <Detector class="com.h3xstream.findsecbugs.crypto.UnencryptedServerSocketDetector"> <Details>暗号化されていないサーバーソケット</Details> </Detector> <BugPattern type="UNENCRYPTED_SERVER_SOCKET"> <ShortDescription>暗号化されていないサーバーソケット</ShortDescription> <LongDescription>暗号化されていないサーバーソケット (SSLServerSocket の代わりに)</LongDescription> <Details> <![CDATA[ <p> 使用される通信チャネルは暗号化されていません。攻撃者がネットワークトラフィックを傍受して,トラフィックが読み取られる可能性があります。 </p> <p> <b>脆弱なコード:</b><br> プレーンサーバーソケット (平文通信): <pre>ServerSocket soc = new ServerSocket(1234);</pre> </p> <p> <b>解決策:</b><br> SSL サーバーソケット (安全な通信): <pre>ServerSocket soc = SSLServerSocketFactory.getDefault().createServerSocket(1234);</pre> </p> <p>SSL サーバーソケットを使用する以外に,<code>SSLServerSocketFactory</code> を使用することで,中間者攻撃の対象にならないように,すべての適切な証明書検証チェックを実行する必要があります。 チェックを正しく行う方法の詳細については,OWASP Transport Layer Protection Cheat Sheet をお読みください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Top_10_2010-A9">OWASP: Top 10 2010-A9-Insufficient Transport Layer Protection</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure">OWASP: Top 10 2013-A6-Sensitive Data Exposure</a><br> <a href="https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet">OWASP: Transport Layer Protection Cheat Sheet</a><br> <a href="http://projects.webappsec.org/w/page/13246945/Insufficient%20Transport%20Layer%20Protection">WASC-04: Insufficient Transport Layer Protection</a><br> <a href="http://cwe.mitre.org/data/definitions/319.html">CWE-319: Cleartext Transmission of Sensitive Information</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECUSS">暗号化されていないサーバーソケット</BugCode> <!-- DES usage --> <Detector class="com.h3xstream.findsecbugs.crypto.DesUsageDetector"> <Details>DES/DESede は AES に置き換えるべきです。</Details> </Detector> <BugPattern type="DES_USAGE"> <ShortDescription>DES/DESede は安全でない</ShortDescription> <LongDescription>DES/DESede は AES に置き換えるべきです。</LongDescription> <Details> <![CDATA[ <p> DES と DESede (3DES) は,今のアプリケーションでは強固な暗号とは見なされていません。現在,NIST は DES/3DES の代わりに AES ブロック暗号の使用を推奨しています。 </p> <p> <b>弱いコードの例:</b> <pre>Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <p> <b>解決例:</b> <pre>Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://www.nist.gov/itl/fips/060205_des.cfm">NIST Withdraws Outdated Data Encryption Standard</a><br> <a href="http://cwe.mitre.org/data/definitions/326.html">CWE-326: Inadequate Encryption Strength</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECDU">DES / DESede</BugCode> <!-- RSA NoPadding --> <Detector class="com.h3xstream.findsecbugs.crypto.cipher.RsaNoPaddingDetector"> <Details>適切なパディングなしの RSA 暗号です。</Details> </Detector> <BugPattern type="RSA_NO_PADDING"> <ShortDescription>パディングなしの RSA 暗号は安全でない</ShortDescription> <LongDescription>適切なパディングなしの RSA 暗号を使用しています。</LongDescription> <Details> <![CDATA[ <p> ソフトウェアは RSA アルゴリズムを使用していますが,最適非対称暗号化パディング (OAEP:Optimal Asymmetric Encryption Padding) を組み込んでいないので,暗号を弱めるかもしれません。 </p> <p> <b>脆弱なコード:</b><br> <pre>Cipher.getInstance("RSA/NONE/NoPadding")</pre> </p> <p> <b>解決策:</b><br> コードは次のように置き換えるべきです:<br> <pre>Cipher.getInstance("RSA/ECB/OAEPWithMD5AndMGF1Padding")</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/780.html">CWE-780: Use of RSA Algorithm without OAEP</a><br> <a href="http://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/">Root Labs: Why RSA encryption padding is critical</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECRNP">パディングなしの RSA 暗号</BugCode> <!-- Hard coded passwords and keys in various method calls --> <Detector class="com.h3xstream.findsecbugs.password.ConstantPasswordDetector"> <Details>ハードコードされたパスワードと鍵を特定します。</Details> </Detector> <!-- Hard coded Google API key --> <Detector class="com.h3xstream.findsecbugs.password.GoogleApiKeyDetector"> <Details>ハードコードされた Google API キーを特定します。</Details> </Detector> <!-- Hard coded JNDI credentials and other password in map --> <Detector class="com.h3xstream.findsecbugs.password.HardcodePasswordInMapDetector"> <Details>マップにハードコードされた認証情報を特定します。</Details> </Detector> <Detector class="com.h3xstream.findsecbugs.password.IntuitiveHardcodePasswordDetector"> <Details>独自 API でハードコードされた認証情報を特定します。</Details> </Detector> <Detector class="com.h3xstream.findsecbugs.password.HardcodedPasswordEqualsDetector"> <Details>password という名前の変数を定数値と比較しているハードコードされた認証情報を特定します。</Details> </Detector> <BugPattern type="HARD_CODE_PASSWORD"> <ShortDescription>ハードコードされたパスワード</ShortDescription> <LongDescription>ハードコードされたパスワードを発見</LongDescription> <Details> <![CDATA[ <p> パスワードをソースコード内に保持すべきではありません。ソースコードは,エンタープライズ環境で広く共有することができ,オープンソースでは確実に共有されます。 安全に管理するためには,パスワードと秘密鍵を別々の設定ファイルやキーストアに格納すべきです。 (ハードコードされた鍵は <i>ハードコードされた鍵</i> パターンで別々に報告されます) </p> <p> <p><b>脆弱なコード:</b><br> <pre>private String SECRET_PASSWORD = "letMeIn!"; Properties props = new Properties(); props.put(Context.SECURITY_CREDENTIALS, "p@ssw0rd");</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/259.html">CWE-259: Use of Hard-coded Password</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHCP">ハードコードされたパスワード</BugCode> <BugPattern type="HARD_CODE_KEY"> <ShortDescription>ハードコードされた鍵</ShortDescription> <LongDescription>ハードコードされた暗号鍵を発見</LongDescription> <Details> <![CDATA[ <p> 暗号鍵をソースコード内に保持すべきではありません。ソースコードは,エンタープライズ環境で広く共有することができ,オープンソースでは確実に共有されます。 安全に管理するためには,パスワードと秘密鍵を別々の設定ファイルやキーストアに格納すべきです。 (ハードコードされたパスワードは <i>ハードコードされたパスワード</i> パターンで別々に報告されます) </p> <p> <p><b>脆弱なコード:</b><br> <pre>byte[] key = {1, 2, 3, 4, 5, 6, 7, 8}; SecretKeySpec spec = new SecretKeySpec(key, "AES"); Cipher aes = Cipher.getInstance("AES"); aes.init(Cipher.ENCRYPT_MODE, spec); return aesCipher.doFinal(secretData);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/321.html">CWE-321: Use of Hard-coded Cryptographic Key</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHCK">ハードコードされた鍵</BugCode> <Detector class="com.h3xstream.findsecbugs.password.HashUnsafeEqualsDetector"> <Details>タイミング攻撃の影響を受けやすいハッシュの安全でない比較を特定します。</Details> </Detector> <BugPattern type="UNSAFE_HASH_EQUALS"> <ShortDescription>安全でないハッシュの比較</ShortDescription> <LongDescription>タイミング攻撃の影響を受けやすいハッシュの安全でない比較です。</LongDescription> <Details> <![CDATA[ <p> 攻撃者は,比較タイミングの暴露による秘密ハッシュ値を検出できる可能性があります。 関数 <code>Arrays.equals()</code> または <code>String.equals()</code> が呼び出されると一致するバイト数が少なければ早く終了します。 </p> <p> <p><b>脆弱なコード:</b><br> <pre> String actualHash = ... if(userInput.equals(actualHash)) { ... }</pre> </p> <p><b>解決策:</b><br> <pre> String actualHash = ... if(MessageDigest.isEqual(userInput.getBytes(),actualHash.getBytes())) { ... }</pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/203.html">CWE-203: Information Exposure Through DiscrepancyKey</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECUHE">Hard Coded Key</BugCode> <!-- Struts Form Validation --> <Detector class="com.h3xstream.findsecbugs.StrutsValidatorFormDetector"> <Details>入力検証がない Struts フォームを特定しました。</Details> </Detector> <BugPattern type="STRUTS_FORM_VALIDATION"> <ShortDescription>入力検証がない Struts フォーム</ShortDescription> <LongDescription>入力検証がない Struts フォーム</LongDescription> <Details> <![CDATA[ <p> フォーム入力には,最低限の入力検証が必要です。予防的な検証は,さまざまなリスクに対して多重防御を提供します。 </p> <p> 検証は,<code>validate</code> メソッドを実装することで導入できます。 <pre> public class RegistrationForm extends ValidatorForm { private String name; private String email; [...] public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { // HttpRequest を介して渡された名前と電子メールパラメーターの検証コードはここに } } </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a><br> <a href="http://cwe.mitre.org/data/definitions/106.html">CWE-106: Struts: Plug-in Framework not in Use</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSFV">入力検証がない Struts フォーム</BugCode> <!-- XSS Filter --> <Detector class="com.h3xstream.findsecbugs.xss.XSSRequestWrapperDetector"> <Details>XSSRequestWrapper (弱い XSS 保護) を特定します。</Details> </Detector> <BugPattern type="XSS_REQUEST_WRAPPER"> <ShortDescription>XSSRequestWrapper は弱い XSS 保護</ShortDescription> <LongDescription>XSSRequestWrapper は弱い XSS 保護メカニズムです。</LongDescription> <Details> <![CDATA[ <p> <code>XSSRequestWrapper</code> と呼ばれる <code>HttpServletRequestWrapper</code> の実装は,さまざまなブログサイトで公開されていました。 <sup><a href="http://java.dzone.com/articles/stronger-anti-cross-site">[1]</a></sup> <sup><a href="http://www.javacodegeeks.com/2012/07/anti-cross-site-scripting-xss-filter.html">[2]</a></sup> </p> <p> フィルタリングはいくつかの理由から弱いです: <ul> <li>カバーしているのはパラメーターだけで,ヘッダーやサイドチャネル入力はカバーしていない</li> <li>置換チェーンは簡単に迂回できる (下の例を参照)</li> <li>非常に特殊な悪いパターンのブラックリスト (良い/有効な入力のホワイトリストではなく)</li> </ul> </p> <p> <b>迂回の例:</b><br> </p> <pre><scrivbscript:pt>alert(1)</scrivbscript:pt></pre> <p> 前述の入力は <b><code>"<script>alert(1)</script>"</code></b> に変換されます。 <code>"vbscript:"</code> の除去は,<code>"<script>.*</script>"</code> の置換が行われた後です。 </p> <p> 強力な保護のために,OWASP XSS Prevention Cheat Sheet で定義されている XSS 保護ルールに従って,<b><u>view</u></b> (template, jsp, ...) で文字を自動的にエンコードする解決策を選択してください。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXRW">XSSRequestWrapper (弱い XSS 保護)</BugCode> <!-- Blowfish key size --> <Detector class="com.h3xstream.findsecbugs.crypto.InsufficientKeySizeBlowfishDetector"> <Details>弱い鍵長での Blowfish の使用を特定します。</Details> </Detector> <BugPattern type="BLOWFISH_KEY_SIZE"> <ShortDescription>短い鍵での Blowfish の使用</ShortDescription> <LongDescription>Blowfish の短い暗号鍵での使用</LongDescription> <Details> <![CDATA[ <p> Blowfish 暗号は,32ビットから448ビットの鍵長をサポートしています。鍵長が短いと,暗号文は総当たり攻撃 (Brute-force attack) に対して脆弱になります。 Blowfish の使用が必要なときは,鍵を生成するときに少なくとも128ビットのエントロピーを使用すべきです。 </p> <p> アルゴリズムを変更できるときは,代わりに AES ブロック暗号を使用すべきです。 </p> <p><b>脆弱なコード:</b><br> <pre>KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish"); keyGen.init(64);</pre> </p> <p><b>解決策:</b><br> <pre>KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish"); keyGen.init(128);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://en.wikipedia.org/wiki/Blowfish_(cipher)">Blowfish (cipher)</a><br> <a href="http://cwe.mitre.org/data/definitions/326.html">CWE-326: Inadequate Encryption Strength</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECBKS">弱い鍵長での Blowfish の使用</BugCode> <!-- RSA key size --> <Detector class="com.h3xstream.findsecbugs.crypto.InsufficientKeySizeRsaDetector"> <Details>弱い鍵長での RSA の使用を特定します。</Details> </Detector> <BugPattern type="RSA_KEY_SIZE"> <ShortDescription>短い鍵長での RSA の使用</ShortDescription> <LongDescription>短い鍵長で RAS を使用しています。</LongDescription> <Details> <![CDATA[ <p> NISTは,RSA アルゴリズムに <u>2048ビット以上</u> の鍵を使用することを推奨しています。 </p> <blockquote> "Digital Signature Verification | RSA: 1024 ≤ len(n) < 2048 | Legacy-use"<br> "Digital Signature Verification | RSA: len(n) ≥ 2048 | Acceptable"<br> - <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths p.7</a> </blockquote> <p><b>脆弱なコード:</b><br> <pre> KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(512); </pre> </p> <p><b>解決策:</b><br> KeyPairGenerator の作成は,次のように少なくとも2048ビットの鍵長にすべきです。 <pre> KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://csrc.nist.gov/groups/ST/toolkit/key_management.html">NIST: Latest publication on key management</a><br> <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf">NIST: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths p.7</a><br> <a href="http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/how-large-a-key-should-be-used.htm">RSA Laboratories: 3.1.5 How large a key should be used in the RSA cryptosystem?</a><br> <a href="http://en.wikipedia.org/wiki/Key_size#Asymmetric%5Falgorithm%5Fkey%5Flengths">Wikipedia: Asymmetric algorithm key lengths</a><br> <a href="http://cwe.mitre.org/data/definitions/326.html">CWE-326: Inadequate Encryption Strength</a><br> <a href="http://www.keylength.com/en/compare/">Keylength.com (BlueKrypt): Aggregate key length recommendations.</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECRKS">弱い鍵長での RSA の使用</BugCode> <!-- Unvalidated redirect --> <Detector class="com.h3xstream.findsecbugs.injection.redirect.UnvalidatedRedirectDetector"> <Details>Java EE API での未検証のリダイレクトを特定します。</Details> </Detector> <Detector class="com.h3xstream.findsecbugs.scala.PlayUnvalidatedRedirectDetector"> <Details>Play Framework での未検証のリダイレクトを特定します。(Scala)</Details> </Detector> <Detector class="com.h3xstream.findsecbugs.spring.SpringUnvalidatedRedirectDetector"> <Details>Spring Framework での未検証のリダイレクトを特定します。</Details> </Detector> <BugPattern type="UNVALIDATED_REDIRECT"> <ShortDescription>未検証のリダイレクト</ShortDescription> <LongDescription>攻撃者は,次のリダイレクトを使用してユーザーをフィッシング Web サイトにリダイレクトできます。</LongDescription> <Details> <![CDATA[ <p> 検証されていないユーザー指定のパラメーターで指定された宛先 URL にユーザーをリダイレクトすると未検証のリダイレクトが発生します。 このような脆弱性を利用して,フィッシング攻撃を容易にすることができます。 </p> <p> <b>シナリオ</b><br> 1. ユーザーは,悪意のある URL にアクセスするようにだまされる: <code>http://website.com/login?redirect=http://evil.vvebsite.com/fake/login</code><br> 2. ユーザーは,信頼できるサイトのように見える偽のログインページにリダイレクトされる。(<code>http://evil.vvebsite.com/fake/login</code>)<br> 3. ユーザーは自分の認証情報を入力する。<br> 4. 悪意のあるサイトはユーザーの認証情報を盗み,元の Web サイトにリダイレクトする。<br> <br> ほとんどのユーザーがリダイレクト後に URL をダブルチェックしないため,この攻撃はもっともらしく思われます。また,認証ページへのリダイレクトもよくあります。 </p> <p> <b>脆弱なコード:</b></br/> <pre>protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { [...] resp.sendRedirect(req.getParameter("redirectUrl")); [...] }</pre> </p> <p> <b>解決策/対策:</b><br> <ul> <li>ユーザーからリダイレクト先を受け入れない</li> <li>宛先キーを受け入れ,それを使用して対象 (合法) の宛先をルックアップする</li> <li>相対パスだけを受け入れる</li> <li>URL のホワイトリスト (可能な場合)</li> <li>URL の先頭がホワイトリストの一部であることを検証する</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246981/URL%20Redirector%20Abuse">WASC-38: URL Redirector Abuse</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A10-Unvalidated_Redirects_and_Forwards">OWASP: Top 10 2013-A10: Unvalidated Redirects and Forwards</a><br> <a href="https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet">OWASP: Unvalidated Redirects and Forwards Cheat Sheet</a><br> <a href="http://cwe.mitre.org/data/definitions/601.html">CWE-601: URL Redirection to Untrusted Site ('Open Redirect')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECUR">未検証のリダイレクト</BugCode> <BugPattern type="PLAY_UNVALIDATED_REDIRECT"> <ShortDescription>未検証のリダイレクト (Play Framework)</ShortDescription> <LongDescription>攻撃者は,次のリダイレクトを使用してユーザーをフィッシング Web サイトにリダイレクトできます。</LongDescription> <Details> <![CDATA[ <p> 検証されていないユーザー指定のパラメーターで指定された宛先 URL にユーザーをリダイレクトすると未検証のリダイレクトが発生します。 このような脆弱性を利用して,フィッシング攻撃を容易にすることができます。 </p> <p> <b>シナリオ</b><br> 1. ユーザーは,悪意のある URL にアクセスするようにだまされる: <code>http://website.com/login?redirect=http://evil.vvebsite.com/fake/login</code><br> 2. ユーザーは,信頼できるサイトのように見える偽のログインページにリダイレクトされる。(<code>http://evil.vvebsite.com/fake/login</code>)<br> 3. ユーザーは自分の認証情報を入力する。<br> 4. 悪意のあるサイトはユーザーの認証情報を盗み,元の Web サイトにリダイレクトする。<br> <br> ほとんどのユーザーがリダイレクト後に URL をダブルチェックしないため,この攻撃はもっともらしく思われます。また,認証ページへのリダイレクトもよくあります。 </p> <p> <b>脆弱なコード:</b></br/> <pre>def login(redirectUrl:String) = Action { [...] Redirect(url) }</pre> </p> <p> <b>解決策/対策:</b><br> <ul> <li>ユーザーからリダイレクト先を受け入れない</li> <li>宛先キーを受け入れ,それを使用して対象 (合法) の宛先をルックアップする</li> <li>相対パスだけを受け入れる</li> <li>URL のホワイトリスト (可能な場合)</li> <li>URL の先頭がホワイトリストの一部であることを検証する</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246981/URL%20Redirector%20Abuse">WASC-38: URL Redirector Abuse</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A10-Unvalidated_Redirects_and_Forwards">OWASP: Top 10 2013-A10: Unvalidated Redirects and Forwards</a><br> <a href="https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet">OWASP: Unvalidated Redirects and Forwards Cheat Sheet</a><br> <a href="http://cwe.mitre.org/data/definitions/601.html">CWE-601: URL Redirection to Untrusted Site ('Open Redirect')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECPUR">未検証のリダイレクト (Play Framewok)</BugCode> <BugPattern type="SPRING_UNVALIDATED_REDIRECT"> <ShortDescription>未検証のリダイレクト (Spring Freamework)</ShortDescription> <LongDescription>攻撃者は,次のリダイレクトを使用してユーザーをフィッシング Web サイトにリダイレクトできます。</LongDescription> <Details> <![CDATA[ <p> 検証されていないユーザー指定のパラメーターで指定された宛先 URL にユーザーをリダイレクトすると未検証のリダイレクトが発生します。 このような脆弱性を利用して,フィッシング攻撃を容易にすることができます。 </p> <p> <b>シナリオ</b><br> 1. ユーザーは,悪意のある URL にアクセスするようにだまされる: <code>http://website.com/login?redirect=http://evil.vvebsite.com/fake/login</code><br> 2. ユーザーは,信頼できるサイトのように見える偽のログインページにリダイレクトされる。(<code>http://evil.vvebsite.com/fake/login</code>)<br> 3. ユーザーは自分の認証情報を入力する。<br> 4. 悪意のあるサイトはユーザーの認証情報を盗み,元の Web サイトにリダイレクトする。<br> <br> ほとんどのユーザーがリダイレクト後に URL をダブルチェックしないため,この攻撃はもっともらしく思われます。また,認証ページへのリダイレクトもよくあります。 </p> <p> <b>脆弱なコード:</b></br/> <pre>@RequestMapping("/redirect") public String redirect(@RequestParam("url") String url) { [...] return "redirect:" + url; }</pre> </p> <p> <b>解決策/対策:</b><br> <ul> <li>ユーザーからリダイレクト先を受け入れない</li> <li>宛先キーを受け入れ,それを使用して対象 (合法) の宛先をルックアップする</li> <li>相対パスだけを受け入れる</li> <li>URL のホワイトリスト (可能な場合)</li> <li>URL の先頭がホワイトリストの一部であることを検証する</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246981/URL%20Redirector%20Abuse">WASC-38: URL Redirector Abuse</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A10-Unvalidated_Redirects_and_Forwards">OWASP: Top 10 2013-A10: Unvalidated Redirects and Forwards</a><br> <a href="https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet">OWASP: Unvalidated Redirects and Forwards Cheat Sheet</a><br> <a href="http://cwe.mitre.org/data/definitions/601.html">CWE-601: URL Redirection to Untrusted Site ('Open Redirect')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSUR">未検証のリダイレクト (Spring Freamework)</BugCode> <!-- JSP Include --> <Detector class="com.h3xstream.findsecbugs.jsp.JspIncludeDetector"> <Details>リモートユーザーが制御できる動的入力を取得する JSP インクルードを特定します。</Details> </Detector> <BugPattern type="JSP_INCLUDE"> <ShortDescription>動的 JSP インクルード</ShortDescription> <LongDescription>JSP を動的にインクルードすると任意のコードが実行される可能性があります。</LongDescription> <Details> <![CDATA[ <p>JSP ファイルをインクルードすることで,動的な値を入力できます。攻撃者がインクルードする JSP ページを制御する可能性があります。 その場合,攻撃者は自分が制御しているディスクにファイルを含めるように試みます。任意のファイルを含めることにより,攻撃者は任意のコードを実行できます。 </p> <p> <b>脆弱なコード:</b> <pre><jsp:include page="${param.secret_param}" /></pre> </p> <p> <b>解決策:</b> <pre><c:if test="${param.secret_param == 'page1'}"> <jsp:include page="page1.jsp" /> </c:if></pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://resources.infosecinstitute.com/file-inclusion-attacks/">InfosecInstitute: File Inclusion Attacks</a><br> <a href="http://projects.webappsec.org/w/page/13246955/Remote%20File%20Inclusion">WASC-05: Remote File Inclusion</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECJSPINC">動的 JSP インクルード</BugCode> <!-- Spring eval --> <Detector class="com.h3xstream.findsecbugs.jsp.JspSpringEvalDetector"> <Details>Spring 式における動的変数の意図しない使用を特定します。</Details> </Detector> <BugPattern type="JSP_SPRING_EVAL"> <ShortDescription>Spring 式の動的変数</ShortDescription> <LongDescription>Spring 式の動的変数によって任意のコードが実行されます。</LongDescription> <Details> <![CDATA[ <p>Spring 式は,動的な値で構築されています。フィルタリングされていない値がこの危険なコード評価になることを避けるために値の発生源を検証すべきです。 </p> <p> <b>脆弱なコード:</b> <pre><%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <spring:eval expression="${param.lang}" var="lang" /></pre> <br> <pre><%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <spring:eval expression="'${param.lang}'=='fr'" var="languageIsFrench" /></pre> </p> <p> <b>解決策:</b> <pre><c:set var="lang" value="${param.lang}"/></pre> <br> <pre><c:set var="languageIsFrench" value="${param.lang == 'fr'}"/></pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/94.html">CWE-94: Improper Control of Generation of Code ('Code Injection')</a><br> <a href="http://cwe.mitre.org/data/definitions/95.html">CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECJSPSPRING">Spring 式の動的変数</BugCode> <!-- JSTL OUT --> <Detector class="com.h3xstream.findsecbugs.jsp.JstlOutDetector"> <Details>特殊な XML 文字のエスケープが無効になっている出力を検出します。</Details> </Detector> <BugPattern type="JSP_JSTL_OUT"> <ShortDescription>特別な XML 文字のエスケープが無効です。</ShortDescription> <LongDescription>特殊な XML 文字のエスケープを無効にすると XSS 脆弱性が発生する可能性があります。</LongDescription> <Details> <![CDATA[ <p> 潜在的な XSS を発見しました。クライアントのブラウザで望まれていない JavaScript を実行するために使用される可能性があります。(参考文献を参照) </p> <p> <b>脆弱なコード:</b> <pre><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <c:out value="${param.test_param}" escapeXml="false"/></pre> </p> <p> <b>解決策:</b> <pre><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <c:out value="${param.test_param}"/></pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a><br> <a href="http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/out.html">JSTL Javadoc: Out tag</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECJSPJSTL">特別な XML 文字のエスケープが無効</BugCode> <!-- XSS in JSP --> <Detector class="com.h3xstream.findsecbugs.xss.XssJspDetector"> <Details>JSP 内の潜在的な XSSを特定します。</Details> </Detector> <BugPattern type="XSS_JSP_PRINT"> <ShortDescription>JSP 内の潜在的な XSS</ShortDescription> <LongDescription>JSP 内の潜在的な XSS</LongDescription> <Details> <![CDATA[ <p> 潜在的な XSS を発見しました。クライアントのブラウザで望まれていない JavaScript を実行するために使用される可能性があります。(参考文献を参照) </p> <p> <b>脆弱なコード:</b> <pre><% String taintedInput = (String) request.getAttribute("input"); %> [...] <%= taintedInput %></pre> </p> <p> <b>解決策:</b> <pre> <% String taintedInput = (String) request.getAttribute("input"); %> [...] <%= Encode.forHtml(taintedInput) %> </pre> </p> <p> XSS に対する最善の防御は,上記の例のような特定の状況で使える出力エンコーディングです。 考慮すべきコンテキストは4つあります: HTML,JavaScript,CSS (スタイル),URL です。 OWASP XSS Prevention Cheat Sheet で定義されている XSS 保護ルールに従ってください。これらの防御について詳細に説明しています。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a><br> <a href="https://code.google.com/p/owasp-java-encoder/">OWASP Java Encoder</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXSS1">JSP 内の潜在的な XSS</BugCode> <Detector class="com.h3xstream.findsecbugs.xss.XssServletDetector"> <Details>HttpServlet.内の潜在的な XSS を特定します。</Details> </Detector> <!-- XSS in Servlet --> <BugPattern type="XSS_SERVLET"> <ShortDescription>サーブレット内の潜在的な XSS</ShortDescription> <LongDescription>{3} の使用は,XSS に対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> 潜在的な XSS を発見しました。クライアントのブラウザで望まれていない JavaScript を実行するために使用される可能性があります。(参考文献を参照) </p> <p> <b>脆弱なコード:</b> <pre>protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String input1 = req.getParameter("input1"); [...] resp.getWriter().write(input1); }</pre> </p> <p> <b>解決策:</b> <pre>protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String input1 = req.getParameter("input1"); [...] resp.getWriter().write(Encode.forHtml(input1)); }</pre> </p> <p> XSSに対する最善の防御は,上記の例のような特定の状況で使える出力エンコーディングです。 考慮すべきコンテキストは4つあります: HTML,JavaScript,CSS (スタイル),URL です。 OWASP XSS Prevention Cheat Sheet で定義されている XSS 保護ルールに従ってください。これらの防御について詳細に説明しています。 </p> <p>サーブレット XSS ルールは類似の問題を探しますが,既存の SpotBugs のルール「XSS:型クロスサイトスクリプティング脆弱性があるサーブレット」と 「XSS:反射型クロスサイトスクリプティング脆弱性がエラーページにあるサーブレット」とは異なる方法で探します。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a><br> <a href="https://code.google.com/p/owasp-java-encoder/">OWASP Java Encoder</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXSS2">サーブレット内の潜在的な XSS</BugCode> <!-- XML decoder --> <Detector class="com.h3xstream.findsecbugs.xml.XmlDecoderDetector"> <Details>XMLDecoder (危険な XML シリアライザー) の使用を特定します。</Details> </Detector> <BugPattern type="XML_DECODER"> <ShortDescription>XMLDecoder の使用</ShortDescription> <LongDescription>XMLDecoder を使用してユーザーから与えられたデータを解析することは安全ではありません。</LongDescription> <Details> <![CDATA[ <p> 信頼できないデータを解析するために <code>XMLDecoder</code> を使用すべきではありません。ユーザー入力をデシリアライズすると任意のコードが実行される可能性があります。 これは,<code>XMLDecoder</code> が任意のメソッド呼び出しをサポートしているので可能です。この機能はセッターメソッドを呼び出すことを意図していますが,実際にはどんなメソッドも呼び出せます。 </p> <p> <b>悪意のある XML の例</b> </p> <pre> <?xml version="1.0" encoding="UTF-8" ?> <java version="1.4.0" class="java.beans.XMLDecoder"> <object class="java.io.PrintWriter"> <string>/tmp/Hacked.txt</string> <void method="println"> <string>Hello World!</string> </void> <void method="close"/> </object> </java> </pre> <p> 上記の XML コードはコンテンツ "Hello World!" を持つファイルが作成されます。 </p> <p> <b>脆弱なコード:</b></br/> <pre>XMLDecoder d = new XMLDecoder(in); try { Object result = d.readObject(); } [...]</pre> </p> <p> <b>解決策:</b></br/> 解決策は,信頼できないソースからのコンテンツの解析に <code>XMLDecoder</code> を使用しないようにすることです。 </p> <br> <p> <b>参考文献</b><br> <a href="http://blog.diniscruz.com/2013/08/using-xmldecoder-to-execute-server-side.html">Dinis Cruz Blog: Using XMLDecoder to execute server-side Java Code on an Restlet application</a><br> <a href="https://securityblog.redhat.com/2014/01/23/java-deserialization-flaws-part-2-xml-deserialization/">RedHat blog : Java deserialization flaws: Part 2, XML deserialization</a><br> <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="XMLDEC">XMLDecoder の使用</BugCode> <!-- Static IV --> <Detector class="com.h3xstream.findsecbugs.crypto.StaticIvDetector"> <Details>正しく生成されていない初期化ベクトル (IV) を特定します。</Details> </Detector> <BugPattern type="STATIC_IV"> <ShortDescription>静的な初期化ベクトル (Static IV)</ShortDescription> <LongDescription>初期化ベクトル (IV) が正しく生成されていません。</LongDescription> <Details> <![CDATA[ <p> 暗号化するメッセージごとに初期化ベクトル (IV:Initialization vector) を再生成する必要があります。 </p> <p><b>脆弱なコード:</b></p> <p> <pre> private static byte[] IV = new byte[16] {(byte)0,(byte)1,(byte)2,[...]}; public void encrypt(String message) throws Exception { IvParameterSpec ivSpec = new IvParameterSpec(IV); [...] </pre> <p><b>解決策:</b></p> <p> <pre> public void encrypt(String message) throws Exception { byte[] iv = new byte[16]; new SecureRandom().nextBytes(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv); [...] </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://en.wikipedia.org/wiki/Initialization_vector">Wikipedia: Initialization vector</a><br> <a href="http://cwe.mitre.org/data/definitions/329.html">CWE-329: Not Using a Random IV with CBC Mode</a><br> <a href="https://defuse.ca/cbcmodeiv.htm">Encryption - CBC Mode IV: Secret or Not?</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="STAIV">静的な初期化ベクトル (Static IV)</BugCode> <!-- Ciphers with no integrity --> <Detector class="com.h3xstream.findsecbugs.crypto.CipherWithNoIntegrityDetector"> <Details>整合性を提供しない暗号を特定します。</Details> </Detector> <!-- ECB Mode --> <BugPattern type="ECB_MODE"> <ShortDescription>ECB モードは安全でない</ShortDescription> <LongDescription>暗号は,暗号化されたデータの機密性が低い ECB モードを使用しています。</LongDescription> <Details> <![CDATA[ <p>守秘義務のない Electronic Codebook (ECB) モードの代わりに暗号化されたデータのより良い機密性を提供する認証暗号モードを使用すべきです。 特に,ECB モードは毎回同じ入力に対して同じ出力を生成します。たとえば,ユーザーがパスワードを送信するとき,暗号化された値は毎回同じです。 これにより,攻撃者はデータを傍受して再生することができます。</p> <p> 修正するためには,Galois/Counter Mode (GCM) のようなものを代わりに使用すべきです。 </p> <p> <b>リスクのあるコード:</b> <pre>Cipher c = Cipher.getInstance("AES/ECB/NoPadding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <p> <b>解決策:</b> <pre>Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://en.wikipedia.org/wiki/Authenticated_encryption">Wikipedia: Authenticated encryption</a><br> <a href="http://csrc.nist.gov/groups/ST/toolkit/BCM/modes_development.html#01">NIST: Authenticated Encryption Modes</a><br> <a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29">Wikipedia: Block cipher modes of operation</a><br> <a href="http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf">NIST: Recommendation for Block Cipher Modes of Operation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECECB">ECB モード</BugCode> <!-- Padding oracle --> <BugPattern type="PADDING_ORACLE"> <ShortDescription>パディングオラクル攻撃の影響を受けやすい暗号</ShortDescription> <LongDescription>暗号はパディングオラクル攻撃の影響を受けやすいです。</LongDescription> <Details> <![CDATA[ <p> この特定のモード (PKCS5Padding を使った CBC) は,パッディングオラクル攻撃の影響を受けやすいです。 システムが無効または有効なパディングによって平文の違いを暴露すると敵はメッセージを解読できるかもしれません。 有効なパディングと無効なパディングの違いは,通常,各条件に対して返されるエラーメッセージによって明らかにされます。 </p> <p> <b>リスクのあるコード:</b> <pre>Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <p> <b>解決策:</b> <pre>Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://www.infobytesec.com/down/paddingoracle_openjam.pdf">Padding Oracles for the masses (by Matias Soler)</a><br> <a href="http://en.wikipedia.org/wiki/Authenticated_encryption">Wikipedia: Authenticated encryption</a><br> <a href="http://csrc.nist.gov/groups/ST/toolkit/BCM/modes_development.html#01">NIST: Authenticated Encryption Modes</a><br> <a href="http://capec.mitre.org/data/definitions/463.html">CAPEC: Padding Oracle Crypto Attack</a><br> <a href="http://cwe.mitre.org/data/definitions/696.html">CWE-696: Incorrect Behavior Order</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="PADORA">パディングオラクル攻撃の影響を受けやすい暗号</BugCode> <!-- Integrity missing --> <BugPattern type="CIPHER_INTEGRITY"> <ShortDescription>整合性のない暗号</ShortDescription> <LongDescription>暗号はデータの整合性を提供していません。</LongDescription> <Details> <![CDATA[ <p> 生成された暗号文は,攻撃者によって改ざんされやすいです。これは,データが改ざんされたことを検出する方法を暗号が提供しないことを意味します。 暗号文が攻撃者によって制御される可能性があると検出されることなく変更される可能性があります。 </p> <p> 解決策は,データに署名するためのハッシュベースのメッセージ認証コード (HMAC:Hash-based Message Authentication Code) を含む暗号を使用することです。 HMAC 関数を既存の暗号と組み合わせると,エラーが発生しやすくなります <sup><a href="http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/">[1]</a></sup>。 具体的には,常に HMAC を最初に検証できることが推奨されます。データが変更されていないときに限り,データに対して暗号化関数を実行します。 </p> <p>次のモードは,HMAC を提供しないため脆弱です。<br> - CBC<br> - OFB<br> - CTR<br> - ECB<br><br> 次のスニペットコードは,脆弱なコードの例です。<br><br> <b>リスクのあるコード:</b><br> <i>CBC モードで AES</i><br> <pre>Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> <br> <i>ECB モードのトリプル DES</i><br> <pre>Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <p> <b>解決策:</b> <pre>Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText);</pre> </p> <p> 上記の解決例では,GCM モードは結果の暗号化されたデータに HMAC を導入し,結果の完全性を提供します。 </p> <br> <p> <b>参考文献</b><br> <a href="http://en.wikipedia.org/wiki/Authenticated_encryption">Wikipedia: Authenticated encryption</a><br> <a href="http://csrc.nist.gov/groups/ST/toolkit/BCM/modes_development.html#01">NIST: Authenticated Encryption Modes</a><br> <a href="http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/">Moxie Marlinspike's blog: The Cryptographic Doom Principle</a><br> <a href="http://cwe.mitre.org/data/definitions/353.html">CWE-353: Missing Support for Integrity Check</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="CIPINT">整合性のない暗号</BugCode> <!-- ESAPI Encryptor --> <Detector class="com.h3xstream.findsecbugs.crypto.EsapiEncryptorDetector"> <Details>ESAPI Encryptor の使用を特定します。</Details> </Detector> <BugPattern type="ESAPI_ENCRYPTOR"> <ShortDescription>ESAPI Encryptor の使用</ShortDescription> <LongDescription>データを暗号化するために ESAPI Encryptor API が使用されています。</LongDescription> <Details> <![CDATA[ <p> ESAPI には,暗号化コンポーネント内にちょっとした脆弱性の前歴があります。 ここでは,認証付き暗号 (Authenticated Encryption) が期待どおりに機能しているかどうかを確認する簡単な検証リストを示します。 </p> <p><b>1. ライブラリのバージョン</b></p> <p> この問題は,ESAPI のバージョン 2.1.0 で修正されています。バージョン 2.0.1 以前は,MAC バイパスに対して脆弱です (CVE-2013-5679)。<br> </p> <p> Maven ユーザーならプラグイン <a href="http://mojo.codehaus.org/versions-maven-plugin/">versions</a> を次のコマンドを使用して呼び出せます。 ESAPI の有効なバージョンは,その出力から入手できます。<br> <pre>$ mvn versions:display-dependency-updates</pre> <br>出力:<br> <pre> [...] [INFO] The following dependencies in Dependencies have newer versions: [INFO] org.slf4j:slf4j-api ................................... 1.6.4 -> 1.7.7 [INFO] org.owasp.esapi:esapi ................................. 2.0.1 -> 2.1.0 [...] </pre> </p> <p> または,直接設定を見ることによって.<br> <pre> <dependency> <groupId>org.owasp.esapi</groupId> <artifactId>esapi</artifactId> <version>2.1.0</version> </dependency></pre> </p> <p> Ant ユーザーなら使用する jar は <a href="http://repo1.maven.org/maven2/org/owasp/esapi/esapi/2.1.0/esapi-2.1.0.jar">esapi-2.1.0.jar</a> でなければなりません。 </p> <p><b>2. 設定:</b></p> <p> ライブラリバージョン 2.1.0 は,いまだに暗号文定義で鍵長が変更されると脆弱です (CVE-2013-5960)。いくつかの予防措置を講ずる必要があります。<br> <br> <div><b>これらの要素のいずれかが存在すると ESAPI の暗号化設定も脆弱になる可能性があります:</b><br> <b>安全でない設定:</b><br> <pre> Encryptor.CipherText.useMAC=false Encryptor.EncryptionAlgorithm=AES Encryptor.CipherTransformation=AES/CBC/PKCS5Padding Encryptor.cipher_modes.additional_allowed=CBC</pre> </div> </p> <p> <div> <b>Secure configuration:</b><br> <pre> #必要 Encryptor.CipherText.useMAC=true #信頼できる認証が必要 Encryptor.EncryptionAlgorithm=AES Encryptor.CipherTransformation=AES/GCM/NoPadding #パディングオラクルを避けるために CBC モードを削除すべき Encryptor.cipher_modes.additional_allowed=</pre> </div> </p> <br> <p> <b>参考文献</b><br> <a href="http://owasp-esapi-java.googlecode.com/svn/trunk/documentation/ESAPI-security-bulletin1.pdf">ESAPI Security bulletin 1 (CVE-2013-5679)</a><br> <a href="http://nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-5679">Vulnerability Summary for CVE-2013-5679</a><br> <a href="http://www.synacktiv.com/ressources/synacktiv_owasp_esapi_hmac_bypass.pdf">Synactiv: Bypassing HMAC validation in OWASP ESAPI symmetric encryption</a><br> <a href="http://cwe.mitre.org/data/definitions/310.html">CWE-310: Cryptographic Issues</a><br> <a href="http://lists.owasp.org/pipermail/esapi-dev/2015-March/002533.html">ESAPI-dev mailing list: Status of CVE-2013-5960</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="ESAPIENC">ESAPI Encryptor</BugCode> <!-- Android: External File Access --> <Detector class="com.h3xstream.findsecbugs.android.ExternalFileAccessDetector"> <Details>外部ストレージへのファイルアクセスを特定します。</Details> </Detector> <BugPattern type="ANDROID_EXTERNAL_FILE_ACCESS"> <ShortDescription>外部ファイルアクセス (Android)</ShortDescription> <LongDescription>ファイルを外部ストレージに保存できる可能性があります。</LongDescription> <Details> <![CDATA[ <p> アプリケーションは外部ストレージ (SD カード) にデータを書き込みます。このアクションには複数のセキュリティの影響があります。 まず,SD カード上のファイルストアは,<a href="http://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE"><code>READ_EXTERNAL_STORAGE</code></a> 権限を持つアプリケーションからアクセスできるようになります。 また,永続化されたデータにユーザーに関する機密情報が含まれているときは,暗号化が必要になります。 </p> <p> <b>リスクのあるコード:</b><br> <pre> file file = new File(getExternalFilesDir(TARGET_TYPE), filename); fos = new FileOutputStream(file); fos.write(confidentialData.getBytes()); fos.flush(); </pre> </p> <p> <b>より良い代替手段:</b><br> <pre> fos = openFileOutput(filename, Context.MODE_PRIVATE); fos.write(string.getBytes()); </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://developer.android.com/training/articles/security-tips.html#ExternalStorage">Android Official Doc: Security Tips</a><br> <a href="https://www.securecoding.cert.org/confluence/display/java/DRD00-J.+Do+not+store+sensitive+information+on+external+storage+%28SD+card%29+unless+encrypted+first">CERT: DRD00-J: Do not store sensitive information on external storage [...]</a><br> <a href="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal">Android Official Doc: Using the External Storage</a><br> <a href="https://www.owasp.org/index.php/Mobile_Top_10_2014-M2">OWASP Mobile Top 10 2014-M2: Insecure Data Storage</a><br> <a href="https://cwe.mitre.org/data/definitions/312.html">CWE-312: Cleartext Storage of Sensitive Information</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECEFA">外部ファイルアクセス (Android)</BugCode> <!-- Android: Broadcast --> <Detector class="com.h3xstream.findsecbugs.android.BroadcastDetector"> <Details>sendBroadcast() の呼び出しを特定し,セキュリティへの影響と有益なガイドラインを提供します。</Details> </Detector> <BugPattern type="ANDROID_BROADCAST"> <ShortDescription>ブロードキャスト (Android)</ShortDescription> <LongDescription>ブロードキャストインテントは,悪意のあるアプリケーションによって受信される可能性があります。</LongDescription> <Details> <![CDATA[ <p> ブロードキャストインテントは,適切な権限を持つ任意のアプリケーションで受け取ることができます。可能であれば機密情報を送信しないようにすることをお勧めします。 </p> <p> <b>リスクのあるコード:</b><br> <pre> Intent i = new Intent(); i.setAction("com.insecure.action.UserConnected"); i.putExtra("username", user); i.putExtra("email", email); i.putExtra("session", newSessionId); this.sendBroadcast(v1); </pre> </p> <br> <p> <b>解決策 (可能なら):</b><br> <pre> Intent i = new Intent(); i.setAction("com.secure.action.UserConnected"); sendBroadcast(v1); </pre> </p> <br> <p> <b>設定 (receiver)<sup>[1] Source: StackOverflow</sup>:</b><br> <pre> <manifest ...> <!-- Permission declaration --> <permission android:name="my.app.PERMISSION" /> <receiver android:name="my.app.BroadcastReceiver" android:permission="my.app.PERMISSION"> <!-- Permission enforcement --> <intent-filter> <action android:name="com.secure.action.UserConnected" /> </intent-filter> </receiver> ... </manifest> </pre> </p> <p> <b>設定 (sender)<sup>[1] Source: StackOverflow</sup>:</b><br> <pre> <manifest> <!-- We declare we own the permission to send broadcast to the above receiver --> <uses-permission android:name="my.app.PERMISSION"/> <!-- With the following configuration, both the sender and the receiver apps need to be signed by the same developer certificate. --> <permission android:name="my.app.PERMISSION" android:protectionLevel="signature"/> </manifest> </pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://www.securecoding.cert.org/confluence/display/java/DRD03-J.+Do+not+broadcast+sensitive+information+using+an+implicit+intent">CERT: DRD03-J. Do not broadcast sensitive information using an implicit intent</a><br> <a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html#Security">Android Official Doc: BroadcastReceiver (Security)</a><br> <a href="http://developer.android.com/guide/topics/manifest/receiver-element.html">Android Official Doc: Receiver configuration (see <code>android:permission</code>)</a><br> <sup>[1]</sup> <a href="http://stackoverflow.com/a/21513368/89769">StackOverflow: How to set permissions in broadcast sender and receiver in android</a><br> <a href="https://cwe.mitre.org/data/definitions/925.html">CWE-925: Improper Verification of Intent by Broadcast Receiver</a><br> <a href="https://cwe.mitre.org/data/definitions/927.html">CWE-927: Use of Implicit Intent for Sensitive Communication</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECBROAD">ブロードキャスト (Android)</BugCode> <!-- Android: World Writable --> <Detector class="com.h3xstream.findsecbugs.android.WorldWritableDetector"> <Details>作成モード MODE_WORLD_READABLE で書き込まれたファイルを特定します。</Details> </Detector> <BugPattern type="ANDROID_WORLD_WRITABLE"> <ShortDescription>ワールドライタブルファイル (Android)</ShortDescription> <LongDescription>書き込まれたコンテンツは,任意のアプリケーションで見ることができます。</LongDescription> <Details> <![CDATA[ <p> このコンテキストで書き込まれたファイルは,作成モード <code>MODE_WORLD_READABLE</code> を使用しています。 書き込まれたコンテンツが暴露されることは期待した動作ではないかもしれません。 </p> <p> <b>リスクのあるコード:</b><br> <pre> fos = openFileOutput(filename, MODE_WORLD_READABLE); fos.write(userInfo.getBytes()); </pre> </p> <br> <p> <b>解決策 (MODE_PRIVATE の使用):</b><br> <pre> fos = openFileOutput(filename, MODE_PRIVATE); </pre> </p> <p> <b>解決策 (ローカル SQLite データベースの使用):</b><br> おそらく構造化されたデータを格納するための最良の解決策は,ローカルの SQLite データベースを使用することです。 データベースファイルが外部ストレージに作成されていないことを確認してください。実装ガイドラインについては,次の参考文献を参照してください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://www.securecoding.cert.org/confluence/display/java/DRD11-J.+Ensure+that+sensitive+data+is+kept+secure">CERT: DRD11-J. Ensure that sensitive data is kept secure</a><br> <a href="http://developer.android.com/training/articles/security-tips.html#InternalStorage">Android Official Doc: Security Tips</a><br> <a href="http://developer.android.com/reference/android/content/Context.html#MODE_PRIVATE">Android Official Doc: Context.MODE_PRIVATE</a><br> <a href="http://www.vogella.com/tutorials/AndroidSQLite/article.html#databasetutorial_database">vogella.com: Android SQLite database and content provider - Tutorial</a><br> <a href="https://www.owasp.org/index.php/Mobile_Top_10_2014-M2">OWASP Mobile Top 10 2014-M2: Insecure Data Storage</a><br> <a href="https://cwe.mitre.org/data/definitions/312.html">CWE-312: Cleartext Storage of Sensitive Information</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWW">ワールドライタブル (Android)</BugCode> <!-- Android: Geolocation --> <Detector class="com.h3xstream.findsecbugs.android.GeolocationDetector"> <Details>Geolocation API の使用を特定します。</Details> </Detector> <BugPattern type="ANDROID_GEOLOCATION"> <ShortDescription>ジオロケーションがアクティブ化された WebView (Android)</ShortDescription> <LongDescription>ジオロケーションがアクティブ化された WebView</LongDescription> <Details> <![CDATA[ <p> ジオロケーションの取得についてユーザーに確認を求めることをお勧めします。 </p> <p> <b>リスクのあるコード:</b><br> <pre> webView.setWebChromeClient(new WebChromeClient() { @Override public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { callback.invoke(origin, true, false); } }); </pre> </p> <p> <b>Suggested code:</b><br> ジオロケーションのサンプリングを制限し,ユーザーに確認を求めます。 <pre> webView.setWebChromeClient(new WebChromeClient() { @Override public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { callback.invoke(origin, true, false); //Ask the user for confirmation } }); </pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://www.securecoding.cert.org/confluence/display/java/DRD15-J.+Consider+privacy+concerns+when+using+Geolocation+API">CERT: DRD15-J. Consider privacy concerns when using Geolocation API</a><br> <a href="http://en.wikipedia.org/wiki/W3C_Geolocation_API">Wikipedia: W3C Geolocation API</a><br> <a href="http://dev.w3.org/geo/api/spec-source.html">W3C: Geolocation Specification</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECGEO">ジオロケーション (Android)</BugCode> <!-- Android: WebView with JavaScript Enabled --> <Detector class="com.h3xstream.findsecbugs.android.WebViewJavascriptEnabledDetector"> <Details>JavaScript を有効にした WebView を特定します。</Details> </Detector> <BugPattern type="ANDROID_WEB_VIEW_JAVASCRIPT"> <ShortDescription>JavaScript を有効にした WebView (Android)</ShortDescription> <LongDescription>JavaScript を有効にした WebView</LongDescription> <Details> <![CDATA[ <p> WebView で JavaScript を有効にすると XSS の影響を受けやすくなります。潜在的な反映型 XSS,格納型 XSS,DOM XSS についてページレンダリングを検査すべきです。<br> <pre> WebView myWebView = (WebView) findViewById(R.id.webView); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); </pre> </p> <p> <b>リスクのあるコード:</b><br> JavaScript を有効にすることは悪いことではありません。潜在的な XSS に対してバックエンドコードを監査する必要があることを意味します。 XSS は,クライアント側に DOM XSS を導入することもできます。 <pre> function updateDescription(newDescription) { $("#userDescription").html("<p>"+newDescription+"</p>"); } </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://www.technotalkative.com/issue-using-setjavascriptenabled-can-introduce-xss-vulnerabilities-application-review-carefully/">Issue: Using setJavaScriptEnabled can introduce XSS vulnerabilities</a><br> <a href="http://developer.android.com/guide/webapps/webview.html#UsingJavaScript">Android Official Doc: WebView</a><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWVJ">JavaScript を有効にした WebView (Android)</BugCode> <!-- Android: --> <Detector class="com.h3xstream.findsecbugs.android.WebViewJavascriptInterfaceDetector"> <Details>Java ブリッジがある WebView (JavaScript インターフェース).</Details> </Detector> <BugPattern type="ANDROID_WEB_VIEW_JAVASCRIPT_INTERFACE"> <ShortDescription>JavaScript インターフェースがある WebView (Android)</ShortDescription> <LongDescription>JavaScript インターフェースがある WebView</LongDescription> <Details> <![CDATA[ <p> JavaScript インターフェースを使用すると WebView が危険な API にさらされる可能性があります。 WebView で XSS が引き起こされると,そのクラスは悪質な JavaScript コードによって呼び出される可能性があります。 </p> <p> <b>リスクのあるコード:</b><br> <pre> WebView myWebView = (WebView) findViewById(R.id.webView); myWebView.addJavascriptInterface(new FileWriteUtil(this), "fileWriteUtil"); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); [...] class FileWriteUtil { Context mContext; FileOpenUtil(Context c) { mContext = c; } public void writeToFile(String data, String filename, String tag) { [...] } } </pre> </p> <br> <p> <b>参考文献</b><br> <a href="http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29">Android Official Doc: WebView.addJavascriptInterface()</a><br> <a href="https://cwe.mitre.org/data/definitions/749.html">CWE-749: Exposed Dangerous Method or Function</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECWVJI">Java ブリッジがある WebView (Javascript インターフェース) (Android)</BugCode> <!-- Cookie usage --> <Detector class="com.h3xstream.findsecbugs.cookie.CookieFlagsDetector"> <Details>Secure フラグが設定されていないクッキーを特定します。</Details> </Detector> <BugPattern type="INSECURE_COOKIE"> <ShortDescription>Secure フラグがないクッキー</ShortDescription> <LongDescription>HTTP URL にアクセスすると Secure フラグが設定されていないクッキーを平文で送信できる可能性があります。</LongDescription> <Details> <![CDATA[ <p> <code>Secure</code> フラグが設定されていない新しいクッキーが作成されています。 <code>Secure</code> フラグは安全でない通信 (<code>http://</code>) のためにクッキーが送信されないようにするためのブラウザへの指示です。 </p> <p> <b>リスクのあるコード:</b><br> <pre> Cookie cookie = new Cookie("userName",userName); response.addCookie(cookie); </pre> </p> <p> <b>解決策 (具体的な設定):</b><br> <pre> Cookie cookie = new Cookie("userName",userName); cookie.setSecure(true); // Secure flag cookie.setHttpOnly(true); </pre> </p> <p> <b>解決策 (Servlet 3.0 の設定):</b><br> <pre> <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0"> [...] <session-config> <cookie-config> <http-only>true</http-only> <secure>true</secure> </cookie-config> </session-config> </web-app> </pre> </p> <br> <p> <b>Reference</b><br> <a href="https://cwe.mitre.org/data/definitions/614.html">CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute</a><br> <a href="https://cwe.mitre.org/data/definitions/315.html">CWE-315: Cleartext Storage of Sensitive Information in a Cookie</a><br> <a href="https://cwe.mitre.org/data/definitions/311.html">CWE-311: Missing Encryption of Sensitive Data</a><br> <a href="https://www.owasp.org/index.php/SecureFlag">OWASP: Secure Flag</a><br> <a href="https://www.rapid7.com/db/vulnerabilities/http-cookie-secure-flag">Rapid7: Missing Secure Flag From SSL Cookie</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECIC">Secure フラグがないクッキー</BugCode> <BugPattern type="HTTPONLY_COOKIE"> <ShortDescription>HttpOnly フラグがないクッキー</ShortDescription> <LongDescription>HttpOnly フラグが設定されていないクッキーは,ブラウザの悪意のあるスクリプトによって赤色になる可能性があります。</LongDescription> <Details> <![CDATA[ <p> <code>HttpOnly</code> が設定されていない新しいクッキーが作成されています。 <code>HttpOnly</code> フラグは,悪意のあるスクリプトによってクッキーが赤色にならないようにするためのブラウザへの指示です。 ユーザーが XSS の対象になっていると,攻撃者はセッション ID を取得するなどの利益を得ます。 </p> <p> <b>リスクのあるコード:</b><br> <pre> Cookie cookie = new Cookie("email",userName); response.addCookie(cookie); </pre> </p> <p> <b>解決策 (具体的な設定):</b><br> <pre> Cookie cookie = new Cookie("email",userName); cookie.setSecure(true); cookie.setHttpOnly(true); //HttpOnly flag </pre> </p> <p> <b>解決策 (Servlet 3.0 の設定):</b><br> <pre> <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0"> [...] <session-config> <cookie-config> <http-only>true</http-only> <secure>true</secure> </cookie-config> </session-config> </web-app> </pre> </p> <br> <p> <b>Reference</b><br> <a href="http://blog.codinghorror.com/protecting-your-cookies-httponly/">Coding Horror blog: Protecting Your Cookies: HttpOnly</a><br> <a href="https://www.owasp.org/index.php/HttpOnly">OWASP: HttpOnly</a><br> <a href="https://www.rapid7.com/db/vulnerabilities/http-cookie-http-only-flag">Rapid7: Missing HttpOnly Flag From Cookie</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHOC">HttpOnly フラグがないクッキー</BugCode> <!-- Deserialization vulnerability --> <Detector class="com.h3xstream.findsecbugs.serial.ObjectDeserializationDetector"> <Details>オブジェクトデシリアライズを検出します。</Details> </Detector> <BugPattern type="OBJECT_DESERIALIZATION"> <ShortDescription>オブジェクトのデシリアライズが使用されている</ShortDescription> <LongDescription>オブジェクトのデシリアライズが使用されています。{1}</LongDescription> <Details> <![CDATA[ <p> 悪意のある操作のきっかけを許すクラスパスにクラスが存在すると信頼できないデータのオブジェクトのデシリアライズにより,リモートでコードが実行される可能性があります。 </p> <p> ライブラリ開発者は,潜在的な悪意のあるトリガーを提供するクラスを修正する傾向があります。 サービス拒否 <sup>[1]</sup> をもたらすことが知られているクラスはまだあります。 </p> <p> デシリアライゼーションは,脆弱性の歴史上気を付けなければならない操作です。 Java 仮想マシン <sup>[2] [3]</sup> に新しい脆弱性が見つかるとすぐに,Web アプリケーションが脆弱になる可能性があります。 </p> <p> <b>リスクのあるコード:</b><br> <pre> public UserData deserializeObject(InputStream receivedFile) throws IOException, ClassNotFoundException { try (ObjectInputStream in = new ObjectInputStream(receivedFile)) { return (UserData) in.readObject(); } } </pre> </p> <p> <b>解決策:</b><br> <p> リモートユーザーが提供するオブジェクトのデシリアライズをしない。 </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/502.html">CWE-502: Deserialization of Untrusted Data</a><br> <a href="https://www.owasp.org/index.php/Deserialization_of_untrusted_data">Deserialization of untrusted data</a><br> <a href="http://www.oracle.com/technetwork/java/seccodeguide-139067.html#8">Serialization and Deserialization </a><br> <a href="https://github.com/frohoff/ysoserial">A tool for generating payloads that exploit unsafe Java object deserialization</a><br> [1] <a href="https://gist.github.com/coekie/a27cc406fc9f3dc7a70d">Example of Denial of Service using the class java.util.HashSet</a><br> [2] <a href="https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2015-2590">OpenJDK: Deserialization issue in ObjectInputStream.readSerialData() (CVE-2015-2590)</a><br> [3] <a href="https://www.rapid7.com/db/modules/exploit/multi/browser/java_calendar_deserialize">Rapid7: Sun Java Calendar Deserialization Privilege Escalation (CVE-2008-5353)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECOBDES">オブジェクトのデシリアライズが使用されています。</BugCode> <!-- Deserialization vulnerability --> <Detector class="com.h3xstream.findsecbugs.serial.UnsafeJacksonDeserializationDetector"> <Details>Jackson データバインドオブジェクトのデシリアライズを検出します。</Details> </Detector> <BugPattern type="JACKSON_UNSAFE_DESERIALIZATION"> <ShortDescription>安全でない Jackson のデシリアライズ設定</ShortDescription> <LongDescription>安全でない Jackson のデシリアライズ設定が使用されています。{1} {2} {3}</LongDescription> <Details> <![CDATA[ <p>Jackson のデータバインドライブラリが不正に使用され,悪意のある操作のトリガ-を可能にするクラスパスにクラスがあると 信頼できないデータのデシリアライズによりリモートコードが実行される可能性があります。</p> <p> <b>解決策:</b><br> <p> <code>JsonTypeInfo.Id.NAME</code> を介して多態性を使用するときに使用できるタイプとサブタイプを明示的に定義します。 また,ObjectMapper を決して呼び出さないでください。<strong>enableDefaultTyping</strong> (それと,readValue は Object,Serializable,Comparable,または既知のデシリアライズ型を保持する型です)。 </p> <p> <b>リスクのあるコード:</b><br> <pre> public class Example { static class ABean { public int id; public Object obj; } static class AnotherBean { @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) // or JsonTypeInfo.Id.MINIMAL_CLASS public Object obj; } public void example(String json) throws JsonMappingException { ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(); mapper.readValue(json, ABean.class); } public void exampleTwo(String json) throws JsonMappingException { ObjectMapper mapper = new ObjectMapper(); mapper.readValue(json, AnotherBean.class); } } </pre> </p> <p> <b>参考文献</b><br> <a href="https://github.com/FasterXML/jackson-databind/issues/1599">Jackson Deserializer security vulnerability</a><br> <a href="https://github.com/mbechler/marshalsec">Java Unmarshaller Security - Turning your data into code execution</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECUJDES">Jackson データバインドのデシリアライズは安全でない</BugCode> <!-- Deserialization vulnerability --> <Detector class="com.h3xstream.findsecbugs.serial.DeserializationGadgetDetector"> <Details>シリアライズを使用してアプリケーションを脆弱にする弱いクラスを検出します。</Details> </Detector> <BugPattern type="DESERIALIZATION_GADGET"> <ShortDescription>このクラスは,デシリアライゼーションガジェットとして使用できる</ShortDescription> <LongDescription>このクラスは,シリアライズを使用するアプリケーションを脆弱にする可能性があります。</LongDescription> <Details> <![CDATA[ <p> デシリアライゼーションガジェットは,ネイティブシリアライゼーションを使ってリモート API を利用するため,攻撃者によって使用されるクラスです。 このクラスは,readObject メソッド (シリアライズ可能) を使用してデシリアライズにカスタム動作を追加するかシリアライズされたオブジェクト (InvocationHandler) から呼び出されます。 </p> <p> このディテクタは,主に研究者によって使用されることを意図しています。本当に問題なのは,リモート操作にデシリアライズを使用することです。 ガジェットを除去することは,悪用されるリスクを減らすための堅牢な方法です。 </p> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/502.html">CWE-502: Deserialization of Untrusted Data</a><br> <a href="https://www.owasp.org/index.php/Deserialization_of_untrusted_data">Deserialization of untrusted data</a><br> <a href="http://www.oracle.com/technetwork/java/seccodeguide-139067.html#8">Serialization and Deserialization </a><br> <a href="https://github.com/frohoff/ysoserial">A tool for generating payloads that exploit unsafe Java object deserialization</a><br> [1] <a href="https://gist.github.com/coekie/a27cc406fc9f3dc7a70d">Example of Denial of Service using the class java.util.HashSet</a><br> [2] <a href="https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2015-2590">OpenJDK: Deserialization issue in ObjectInputStream.readSerialData() (CVE-2015-2590)</a><br> [3] <a href="https://www.rapid7.com/db/modules/exploit/multi/browser/java_calendar_deserialize">Rapid7: Sun Java Calendar Deserialization Privilege Escalation (CVE-2008-5353)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECDESGAD">デシリアライゼーションガジェット</BugCode> <!-- Trust Boundary Violation --> <Detector class="com.h3xstream.findsecbugs.injection.trust.TrustBoundaryViolationValueDetector"> <Details>セッション属性値への潜在的な望まれていないアクセスを検出します (Trust Boundary Violation)。</Details> </Detector> <Detector class="com.h3xstream.findsecbugs.injection.trust.TrustBoundaryViolationAttributeDetector"> <Details>セッション属性名への潜在的な望まれていないアクセスを検出します (Trust Boundary Violation)。</Details> </Detector> <BugPattern type="TRUST_BOUNDARY_VIOLATION"> <ShortDescription>Trust Boundary Violation</ShortDescription> <LongDescription>アプリケーションは,信頼できるデータと信頼できないデータをセッション属性で混合しています。</LongDescription> <Details> <![CDATA[ <p> 「信頼境界は,プログラム内部に引かれた線と考えることができます。線の片側ではデータは信頼できません。線の反対側では,データは信頼できるものと仮定されます。 検証ロジックの目的は,データが信頼境界を安全に越え,信頼できない側から信頼される側に移れるようにすることです。 信頼されているものと信頼されていないものを分ける線がプログラムで不明確なときに,Trust Boundary Violation が発生します。 信頼できるデータと信頼できないデータを同一のデータ構造で混在させることで,プログラマが誤って検証されていないデータを信頼しやすくなります。」 <sup>[1]</sup> </p> <p> <b>リスクのあるコード:</b><br> <pre> public void doSomething(HttpServletRequest req, String activateProperty) { //.. req.getSession().setAttribute(activateProperty,"true"); } </pre> <br> <pre> public void loginEvent(HttpServletRequest req, String userSubmitted) { //.. req.getSession().setAttribute("user",userSubmitted); } </pre> </p> <p> <b>解決策:</b><br> <p> 解決策は,新しいセッション属性を設定する前に検証を追加することです。可能であれば,ダイレクトユーザー入力の使用よりも安全な場所からのデータを選びます。 </p> <br> <p> <b>参考文献</b><br> [1] <a href="https://cwe.mitre.org/data/definitions/501.html">CWE-501: Trust Boundary Violation</a><br> <a href="https://www.owasp.org/index.php/Trust_Boundary_Violation">OWASP : Trust Boundary Violation</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECTBV">Trust Boundary Violation</BugCode> <!-- JSP XSLT --> <Detector class="com.h3xstream.findsecbugs.jsp.XslTransformJspDetector"> <Details>JSP で行われた XSL 変換を特定します。</Details> </Detector> <BugPattern type="JSP_XSLT"> <ShortDescription>悪意のある XSLT が提供される可能性があります。</ShortDescription> <LongDescription>悪意のある XSLT を提供して,リモートでコードを実行させることができます。</LongDescription> <Details> <![CDATA[ <p> 「XSLT (Extensible Stylesheet Language Transformations) は,XML 文書を他のXML文書に変換するための言語です。」<sup>[1]</sup><br> スタイルシートに悪意のある振る舞いを付けることは可能です。 したがって,攻撃者がスタイルシートの内容やソースを制御できると,攻撃者はリモートでコードの実行をトリガーできる可能性があります。<sup>[2]</sup> </p> <p> <b>リスクのあるコード:</b><br> <pre> <x:transform xml="${xmlData}" xslt="${xsltControlledByUser}" /> </pre> </p> <p> <b>解決策:</b><br> <p> 解決策は,スタイルシートが安全なソースからロードされていることを確認し,パストラバーサル <sup>[3] [4]</sup> のような脆弱性が確実に起こらないようにすることです。 </p> <p> <b>参考文献</b><br> [1] <a href="https://en.wikipedia.org/wiki/XSLT">Wikipedia: XSLT (Extensible Stylesheet Language Transformations)</a><br> <a href="https://prezi.com/y_fuybfudgnd/offensive-xslt/">Offensive XSLT</a> by Nicolas Gregoire<br> [2] <a href="http://www.agarri.fr/kom/archives/2012/07/02/from_xslt_code_execution_to_meterpreter_shells/index.html">From XSLT code execution to Meterpreter shells</a> by Nicolas Gregoire<br> <a href="http://xhe.myxwiki.org/xwiki/bin/view/Main/">XSLT Hacking Encyclopedia</a> by Nicolas Gregoire<br> <a href="http://www.acunetix.com/blog/articles/the-hidden-dangers-of-xsltprocessor-remote-xsl-injection/">Acunetix.com : The hidden dangers of XSLTProcessor - Remote XSL injection</a><br> <a href="https://www.w3.org/TR/xslt">w3.org XSL Transformations (XSLT) Version 1.0</a> : w3c specification<br> [3] <a href="http://projects.webappsec.org/w/page/13246952/Path%20Traversal">WASC: Path Traversal</a><br> [4] <a href="https://www.owasp.org/index.php/Path_Traversal">OWASP: Path Traversal</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECJSPXSLT">悪意のある XSLT が提供される可能性があります。</BugCode> <!-- XSLT --> <Detector class="com.h3xstream.findsecbugs.xml.StdXmlTransformDetector"> <Details>XSL 変換を特定します。</Details> </Detector> <BugPattern type="MALICIOUS_XSLT"> <ShortDescription>悪意のある XSLT が提供される可能性があります。</ShortDescription> <LongDescription>悪意のある XSLT を提供して,リモートでコードを実行させることができます。</LongDescription> <Details> <![CDATA[ <p> 「XSLT (Extensible Stylesheet Language Transformations) は,XML 文書を他のXML文書に変換するための言語です。」<sup>[1]</sup><br> スタイルシートに悪意のある振る舞いを付けることは可能です。 したがって,攻撃者がスタイルシートの内容やソースを制御できると,攻撃者はリモートでコードの実行をトリガーできる可能性があります。<sup>[2]</sup> </p> <p> <b>リスクのあるコード:</b><br> <pre> Source xslt = new StreamSource(new FileInputStream(inputUserFile)); //Dangerous source to validate Transformer transformer = TransformerFactory.newInstance().newTransformer(xslt); Source text = new StreamSource(new FileInputStream("/data_2_process.xml")); transformer.transform(text, new StreamResult(...)); </pre> </p> <p> <b>解決策:</b><br> <p> 解決策は,スタイルシートが安全なソースからロードされていることを確認し,パストラバーサル <sup>[3] [4]</sup> のような脆弱性が確実に起こらないようにすることです。 </p> <p> <b>参考文献</b><br> [1] <a href="https://en.wikipedia.org/wiki/XSLT">Wikipedia: XSLT (Extensible Stylesheet Language Transformations)</a><br> <a href="https://prezi.com/y_fuybfudgnd/offensive-xslt/">Offensive XSLT</a> by Nicolas Gregoire<br> [2] <a href="http://www.agarri.fr/kom/archives/2012/07/02/from_xslt_code_execution_to_meterpreter_shells/index.html">From XSLT code execution to Meterpreter shells</a> by Nicolas Gregoire<br> <a href="http://xhe.myxwiki.org/xwiki/bin/view/Main/">XSLT Hacking Encyclopedia</a> by Nicolas Gregoire<br> <a href="http://www.acunetix.com/blog/articles/the-hidden-dangers-of-xsltprocessor-remote-xsl-injection/">Acunetix.com : The hidden dangers of XSLTProcessor - Remote XSL injection</a><br> <a href="https://www.w3.org/TR/xslt">w3.org XSL Transformations (XSLT) Version 1.0</a> : w3c specification<br> [3] <a href="http://projects.webappsec.org/w/page/13246952/Path%20Traversal">WASC: Path Traversal</a><br> [4] <a href="https://www.owasp.org/index.php/Path_Traversal">OWASP: Path Traversal</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECXSLT">悪意のある XSLT が提供される可能性があります。</BugCode> <!-- Scala sensitive data leak --> <Detector class="com.h3xstream.findsecbugs.scala.ScalaSensitiveDataExposureDetector"> <Details>Scala Play で潜在的な情報漏洩を特定します。</Details> </Detector> <BugPattern type="SCALA_SENSITIVE_DATA_EXPOSURE"> <ShortDescription>Scala Play における潜在的な情報漏洩</ShortDescription> <LongDescription>Scala Play で見つかった設定やシステム情報の漏洩。</LongDescription> <Details> <![CDATA[ <p> アプリケーションは,アプリケーションのさまざまな問題により意図せずに設定や内部の動作に関する情報を漏洩したり,プライバシーを侵害する可能性があります。 <sup>[1]</sup> データの正当性に基づいて異なる応答を提供するページは,情報漏洩につながります。具体的には,Web アプリケーションの設計の結果として機密と見なされるデータが漏洩したときです。<sup>[2]</sup> </p> <p> 機密データの例には,API キー,パスワード,製品バージョン,環境設定が含まれます (ただしこれに限定されません)。 </p> <p> <b>リスクのあるコード:</b><br> <pre>def doGet(value:String) = Action { val configElement = configuration.underlying.getString(value) Ok("Hello "+ configElement +" !") }</pre> </p> <p> アプリケーションの構成要素を応答コンテンツに送信しないでください。また,コードによって使用される構成要素をユーザーが制御できないようにすべきです。 </p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure">OWASP: Top 10 2013-A6-Sensitive Data Exposure</a><br> [1] <a href="https://www.owasp.org/index.php/Top_10_2007-Information_Leakage_and_Improper_Error_Handling">OWASP: Top 10 2007-Information Leakage and Improper Error Handling</a><br> [2] <a href="http://projects.webappsec.org/w/page/13246936/Information%20Leakage">WASC-13: Information Leakage</a><br> <a href="https://cwe.mitre.org/data/definitions/200.html">CWE-200: Information Exposure</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSDL">構成情報またはシステム情報の漏洩</BugCode> <!-- Scala Play Server Side Request Forgery --> <Detector class="com.h3xstream.findsecbugs.scala.SSRFDetector"> <Details>潜在的な Scala Play Server Side Request Forgery (SSRF) を特定します。</Details> </Detector> <BugPattern type="SCALA_PLAY_SSRF"> <ShortDescription>Scala Play Server-Side Request Forgery (SSRF)</ShortDescription> <LongDescription>この Web サーバーリクエストは,内部サービスを暴露するので攻撃者によって利用される可能性があります。</LongDescription> <Details> <![CDATA[ <p> Server-Side Request Forgery (SSRF) は,Web サーバーがユーザーが指定した検証されていない宛先パラメーターへの要求を実行するときに発生します。 このような脆弱性により,攻撃者は内部サービスにアクセスしたり,Web サーバーから攻撃を開始する可能性があります。 </p> <p> <b>脆弱なコード:</b> <pre>def doGet(value:String) = Action { WS.url(value).get().map { response => Ok(response.body) } }</pre> </p> <p> <b>解決策/対策:</b><br> <ul> <li>ユーザーからリクエスト先を受け入れない</li> <li>宛先キーを受け入れ,それを使用して対象 (合法) の宛先をルックアップする</li> <li>URL のホワイトリスト (可能な場合)</li> <li>URL の先頭がホワイトリストの一部であることを検証する</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/918.html">CWE-918: Server-Side Request Forgery (SSRF)</a><br> <a href="https://www.bishopfox.com/blog/2015/04/vulnerable-by-design-understanding-server-side-request-forgery/">Understanding Server-Side Request Forgery</a><br> </p> ]]></Details> </BugPattern> <BugCode abbrev="SECSSSRF">Scala Play Server-Side Request Forgery</BugCode> <BugPattern type="URLCONNECTION_SSRF_FD"> <ShortDescription>URLConnection Server-Side Request Forgery (SSRF) と File Disclosure</ShortDescription> <LongDescription>この Web サーバーリクエストは,内部のサービスとファイルシステムを暴露するので攻撃者によって利用される可能性があります。</LongDescription> <Details> <![CDATA[ <p> Server-Side Request Forgery (SSRF) は,Web サーバーがユーザーが指定した検証されていない宛先パラメーターへの要求を実行するときに発生します。 このような脆弱性により,攻撃者は内部サービスにアクセスしたり,Web サーバーから攻撃を開始する可能性があります。 </p> <p> <code>URLConnection</code> は,file:// プロトコルまたは他のプロトコルと共に使用して,ローカルファイルシステムやその他のサービスにアクセスできます。 <p> <b>脆弱なコード:</b> <pre> new URL(String url).openConnection() new URL(String url).openStream() new URL(String url).getContent() </pre> </p> <p> <b>解決策/対策:</b><br> <ul> <li>ユーザーから URL 宛先を受け入れない</li> <li>宛先キーを受け入れ,それを使用して対象 (合法) の宛先をルックアップする</li> <li>URL のホワイトリスト (可能な場合)</li> <li>URL の先頭がホワイトリストの一部であることを検証する</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/918.html">CWE-918: Server-Side Request Forgery (SSRF)</a><br> <a href="https://www.bishopfox.com/blog/2015/04/vulnerable-by-design-understanding-server-side-request-forgery/">Understanding Server-Side Request Forgery</a><br> <a href="https://cwe.mitre.org/data/definitions/73.html">CWE-73: External Control of File Name or Path</a><br> <a href="https://www.pwntester.com/blog/2013/11/28/abusing-jar-downloads/">Abusing jar:// downloads</a><br> </p> ]]></Details> </BugPattern> <BugCode abbrev="SECSSSRFUC">URLConnection Server-Side Request Forgery</BugCode> <!-- XSS in Scala Play Twirl template engine --> <Detector class="com.h3xstream.findsecbugs.scala.XssTwirlDetector"> <Details>Scala Twirl テンプレートエンジンで潜在的な XSS を特定します。</Details> </Detector> <BugPattern type="SCALA_XSS_TWIRL"> <ShortDescription>Scala Twirl テンプレートエンジンの潜在的な XSS</ShortDescription> <LongDescription>{3} の使用は,XSS に対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> 潜在的な XSS を発見しました。クライアントのブラウザで望まれていない JavaScript を実行するために使用される可能性があります。(参考文献を参照) </p> <p> <b>脆弱なコード:</b> <pre>@(value: Html) @value</pre> </p> <p> <b>解決策:</b> <pre>@(value: String) @value</pre> </p> <p> XSSに対する最善の防御は,上記の例のような特定の状況で使える出力エンコーディングです。考慮すべきコンテキストは,HTML,JavaScript,CSS (スタイル),URL の4つです。 OWASP XSS Prevention Cheat Sheet で定義されている XSS 保護ルールに従ってください。これらの防御について詳細に説明しています。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a><br> <a href="https://code.google.com/p/owasp-java-encoder/">OWASP Java Encoder</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSXSST">Scala Twirl の潜在的な XSS</BugCode> <!-- XSS in Scala Play controller response --> <Detector class="com.h3xstream.findsecbugs.scala.XssMvcApiDetector"> <Details>Scala MVC API エンジンの潜在的な XSS を特定します。</Details> </Detector> <BugPattern type="SCALA_XSS_MVC_API"> <ShortDescription>Scala MVC API エンジンの潜在的な XSS</ShortDescription> <LongDescription>このコンテンツタイプの MVC 結果は,XSS に対して脆弱である可能性があります。</LongDescription> <Details> <![CDATA[ <p> 潜在的な XSS を発見しました。クライアントのブラウザで望まれていない JavaScript を実行するために使用される可能性があります。(参考文献を参照) </p> <p> <b>脆弱なコード:</b> <pre>def doGet(value:String) = Action { Ok("Hello " + value + " !").as("text/html") }</pre> </p> <p> <b>解決策:</b> <pre>def doGet(value:String) = Action { Ok("Hello " + Encode.forHtml(value) + " !") }</pre> </p> <p> XSSに対する最善の防御は,上記の例のような特定の状況で使える出力エンコーディングです。考慮すべきコンテキストは,HTML,JavaScript,CSS (スタイル),URL の4つです。 OWASP XSS Prevention Cheat Sheet で定義されている XSS 保護ルールに従ってください。これらの防御について詳細に説明しています。 </p> <br> <p> <b>参考文献</b><br> <a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting">WASC-8: Cross Site Scripting</a><br> <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">OWASP: XSS Prevention Cheat Sheet</a><br> <a href="https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29">OWASP: Top 10 2013-A3: Cross-Site Scripting (XSS)</a><br> <a href="http://cwe.mitre.org/data/definitions/79.html">CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')</a><br> <a href="https://code.google.com/p/owasp-java-encoder/">OWASP Java Encoder</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSXSS">Scala MVC API の潜在的な XSS</BugCode> <!-- Potential template injection with Velocity --> <Detector class="com.h3xstream.findsecbugs.template.VelocityDetector"> <Details>Velocity テンプレートエンジンの使用を特定します。</Details> </Detector> <BugPattern type="TEMPLATE_INJECTION_VELOCITY"> <ShortDescription>Velocity の潜在的なテンプレートインジェクション</ShortDescription> <LongDescription>Velocity テンプレートの潜在的なテンプレートインジェクションです。</LongDescription> <Details> <![CDATA[ <p> Velocity テンプレートエンジンは強力です。条件文,ループ,外部呼び出しなどのロジックを追加することができます。 テンプレート操作をサンドボックスにすることは設計されていません。テンプレートを制御する悪意のあるユーザーは,サーバー側で悪意のあるコードを実行する可能性があります。 Velocity テンプレートはスクリプトとしてみなすべきです。 </p> <p> <b>脆弱なコード:</b> <pre>[...] Velocity.evaluate(context, swOut, "test", userInput);</pre> </p> <p> <b>解決策:</b> <br> エンドユーザーが Velocity を使用してテンプレートを操作できないようにします。 テンプレート編集をユーザーに公開する必要があるときは,Handlebars や Mustache などのロジックレステンプレートエンジンを使用することをお勧めします。(参考文献を参照) </p> <br> <p> <b>参考文献</b><br> <a href="http://blog.portswigger.net/2015/08/server-side-template-injection.html">PortSwigger: Server-Side Template Injection </a><br> <a href="https://jknack.github.io/handlebars.java/">Handlebars.java</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECVELO">Velocity の潜在的なテンプレートインジェクション</BugCode> <!-- Potential template injection with Freemarker --> <Detector class="com.h3xstream.findsecbugs.template.FreemarkerDetector"> <Details>Freemarker テンプレートエンジンの使用を特定します。</Details> </Detector> <BugPattern type="TEMPLATE_INJECTION_FREEMARKER"> <ShortDescription>Freemarker の潜在的なテンプレートインジェクション</ShortDescription> <LongDescription>Freemarker テンプレートの潜在的なテンプレートインジェクションです。</LongDescription> <Details> <![CDATA[ <p> Freemarker テンプレートエンジンは強力です。条件文,ループ,外部呼び出しなどのロジックを追加することができます。 テンプレート操作をサンドボックスにすることは設計されていません。テンプレートを制御する悪意のあるユーザーは,サーバー側で悪意のあるコードを実行する可能性があります。 Freemarker テンプレートはスクリプトとして見なすべきです。 </p> <p> <b>脆弱なコード:</b> <pre>Template template = cfg.getTemplate(inputTemplate); [...] template.process(data, swOut);</pre> </p> <p> <b>解決策:</b> <br> エンドユーザーが Freemarker を使用してテンプレートを操作できないようにします。 テンプレート編集をユーザーに公開する必要があるときは,Handlebars や Mustache などのロジックレステンプレートエンジンを使用することをお勧めします。(参考文献を参照) </p> <br> <p> <b>参考文献</b><br> <a href="http://blog.portswigger.net/2015/08/server-side-template-injection.html">PortSwigger: Server-Side Template Injection </a><br> <a href="https://jknack.github.io/handlebars.java/">Handlebars.java</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECFREEM">Freemarker の潜在的なテンプレートインジェクション</BugCode> <!-- Overly permissive CORS policy --> <Detector class="com.h3xstream.findsecbugs.PermissiveCORSDetector"> <Details>過度に許可される CORS ポリシーを検出します。</Details> </Detector> <BugPattern type="PERMISSIVE_CORS"> <ShortDescription>過剰に許可される CORS ポリシー</ShortDescription> <LongDescription>このプログラムでは,過剰に許可される クロスオリジンのリソース共有 (CORS:Cross-Origin Resource Sharing) ポリシーを定義しています。</LongDescription> <Details> <![CDATA[ <p> HTML5 以前の Web ブラウザでは,同一生成元ポリシーが強制されます。このポリシーは,JavaScript が Web ページのコンテンツにアクセスするために,JavaScript と Web ページの両方が同じドメインを由来としている必要があります。 同一生成元ポリシーが適用されないと,悪意のある Web サイトはクライアントの認証情報を使用して他の Web サイトから機密情報をロードする JavaScript を仕込むことができ,選び取った情報を攻撃者に返します。 <code>Access-Control-Allow-Origin</code> という新しい HTTP ヘッダーが定義されていると,HTML5 では,JavaScript はドメイン間でデータにアクセスすることが可能です。 生成元間のリクエストを使用してドメインにアクセスすることを許可する他のドメインを,Web サーバーはこのヘッダーを使用して定義します。 しかし,このヘッダーを定義する場合には,注意が必要です。過度に許可された CORS ポリシーは,悪意のあるアプリケーションが不正な方法で攻撃対象のアプリケーションとやりとりをして,偽装,データの盗み出し,リレー,およびその他の攻撃が実行される恐れがあります。 </p> <p> <b>脆弱なコード:</b> <pre>response.addHeader("Access-Control-Allow-Origin", "*");</pre> </p> <p> <b>解決策:</b> <br> <code>Access Control-Allow-Origin</code> ヘッダーの値としてワイルドカード (*) を使用しないでください。アプリケーションのデータが,任意のドメインで実行される JavaScript にアクセスできることになります。 </p> <br> <p> <b>参考文献</b><br> <a href="https://www.w3.org/TR/cors/">W3C Cross-Origin Resource Sharing</a><br> <a href="http://enable-cors.org/">Enable Cross-Origin Resource Sharing</a><br> </p>]]> </Details> </BugPattern> <BugCode abbrev="SECCORS">過剰に許可される CORS ポリシー</BugCode> <!-- LDAP anonymous bind detector --> <Detector class="com.h3xstream.findsecbugs.ldap.AnonymousLdapDetector"> <Details>匿名 LDAP バインドの使用を特定します。</Details> </Detector> <BugPattern type="LDAP_ANONYMOUS"> <ShortDescription>匿名 LDAP バインド</ShortDescription> <LongDescription>匿名 LDAP バインド</LongDescription> <Details> <![CDATA[ <p> 適切なアクセス制御がなく,ユーザーの制御下にある値を含む LDAP ステートメントを実行すると,攻撃者は不適切な設定となっている LDAP 環境を悪用する可能性があります。 <code>ctx</code> に対するすべての LDAP クエリは,認証とアクセス制御なしで実行されます。 攻撃者は予期しない方法でこれらのクエリーのいずれかを操作して,ディレクトリのアクセス制御メカニズムにより保護されているレコードにアクセスする可能性があります。 </p> <p> <b>脆弱なコード:</b> <pre>... env.put(Context.SECURITY_AUTHENTICATION, "none"); DirContext ctx = new InitialDirContext(env); ...</pre> </p> <p> <b>解決策:</b> <br> LDAP に対する他の認証モードを検討し,適切なアクセス制御メカニズムを確保してください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://docs.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html">Ldap Authentication Mechanisms</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="LDAPA">匿名 LDAP バインド</BugCode> <!-- LDAP Entry Poisoning --> <Detector class="com.h3xstream.findsecbugs.ldap.LdapEntryPoisoningDetector"> <Details>LDAP Entry Poisoning を許可する誤った設定を特定します。</Details> </Detector> <BugPattern type="LDAP_ENTRY_POISONING"> <ShortDescription>LDAP Entry Poisoning</ShortDescription> <LongDescription>LDAP Entry Poisoning</LongDescription> <Details> <![CDATA[ <p> JNDI API は,LDAP ディレクトリ内のシリアライズオブジェクトのバインディングをサポートします。 特定の属性が提示されていると,オブジェクトのデシリアライズは,ディレクトリを照会するアプリケーションで行われます (詳細は Black Hat USA 2016ホワイトペーパーを参照)。 オブジェクトのデシリアライズは,リモートでコードが実行される危険な操作として扱うべきです。 </p> <p> LDAP ベースクエリにエントリポイントを持っていると,攻撃者が既存の LDAP エントリに属性を追加するか,悪意のある LDAP サーバーを使用するようにアプリケーションを構成することにより,この脆弱性が悪用される可能性があります。 </p> <p> <b>脆弱なコード:</b> <pre> DirContext ctx = new InitialDirContext(); //[...] ctx.search(query, filter, new SearchControls(scope, countLimit, timeLimit, attributes, true, //Enable object deserialization if bound in directory deref)); </pre> </p> <p> <b>解決策:</b> <pre> DirContext ctx = new InitialDirContext(); //[...] ctx.search(query, filter, new SearchControls(scope, countLimit, timeLimit, attributes, false, //Disable deref)); </pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf">Black Hat USA 2016: A Journey From JNDI/LDAP Manipulation to Remote Code Execution Dream Land</a> (<a href="https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf">slides</a> & <a href="https://www.youtube.com/watch?v=Y8a5nB-vy78">video</a>) by Alvaro Muñoz and Oleksandr Mirosh<br> <a href="https://community.hpe.com/t5/Security-Research/Introducing-JNDI-Injection-and-LDAP-Entry-Poisoning/ba-p/6885118">HP Enterprise: Introducing JNDI Injection and LDAP Entry Poisoning</a> by Alvaro Muñoz<br> <a href="http://blog.trendmicro.com/trendlabs-security-intelligence/new-headaches-how-the-pawn-storm-zero-day-evaded-javas-click-to-play-protection/">TrendMicro: How The Pawn Storm Zero-Day Evaded Java's Click-to-Play Protection</a> by Jack Tang </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECLDAPEP">LDAP Entry Poisoning</BugCode> <!-- Persistent Cookie Usage--> <Detector class="com.h3xstream.findsecbugs.cookie.PersistentCookieDetector"> <Details>永続的なクッキーの使用を特定します。</Details> </Detector> <BugPattern type="COOKIE_PERSISTENT"> <ShortDescription>永続的クッキーの使用</ShortDescription> <LongDescription>1年以上経過したクッキーセット</LongDescription> <Details> <![CDATA[ <p> 永続的なクッキーに機密データを長時間保管すると,機密性が損なわれたり,アカウントが悪用される可能性があります。 </p> <p> <b>説明:</b><br> 永続的クッキーでは有効期限がずっと先に設定されることが多いため,永続的クッキーに個人情報が保管されていると,攻撃者が情報を盗み出すことのできる時間が長くなります。 永続的クッキーは通常,クライアント上のテキストファイルに保存され,被害者のマシンにアクセスできる攻撃者はこの情報を盗む可能性があります。<br> 永続的クッキーは,サイトとやり取りするときのユーザープロファイルとして使用されます。 この追跡データに対して実行される操作によっては,ユーザーの個人情報を盗み出すのに永続的クッキーが使用される可能性があります。 </p> <p> <b>脆弱なコード:</b> 次のコードは,クッキーが1年間で期限切れになるよう設定します。<br> <pre>[...] Cookie cookie = new Cookie("email", email); cookie.setMaxAge(60*60*24*365); [...]</pre> </p> <p> <b>解決策:</b><br> <ul> <li>永続的クッキーは,必要なときにだけ使用し,最高年齢を制限する</li> <li>重要なデータに永続的クッキーを使用しない</li> </ul> </p> <br> <p> <b>参考文献</b><br> <a href="https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/Cookie.html#setMaxAge%28int%29">Class Cookie setMaxAge documentation</a><br> <a href="https://cwe.mitre.org/data/definitions/539.html">CWE-539: Information Exposure Through Persistent Cookies</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECCP">永続的クッキーの使用</BugCode> <!-- URL Rewriting Methods --> <Detector class="com.h3xstream.findsecbugs.cookie.UrlRewritingDetector"> <Details>URL を書き換えるメソッドを検出します。</Details> </Detector> <BugPattern type="URL_REWRITING"> <ShortDescription>URL を書き換えるメソッド</ShortDescription> <LongDescription>セッション ID を URL に書き換えているメソッドです。</LongDescription> <Details> <![CDATA[ <p> このメソッドの実装には,セッション ID を URL にエンコードする必要があるかどうかを判断するロジックが含まれています。<br> URL の書き換えには,セキュリティ上の重大なリスクがあります。セッション ID が URL に表示されるので,第三者が容易に見ることができます。 URL のセッション ID は,さまざまな方法で公開できます。たとえば,次のようになります。<br> <ul> <li>ログファイル</li> <li>ブラウザの履歴</li> <li>電子メールや投稿にコピーアンドペーストすることにより</li> <li>HTTP のリファラ</li> </ul> </p> <p> <b>脆弱なコード:</b><br> <pre>out.println("Click <a href=" + res.encodeURL(HttpUtils.getRequestURL(req).toString()) + ">here</a>");</pre> </p> <p> <b>解決策:</b><br> これらのメソッドを使用しないでください。URL 文字列またはフォームパラメータをエンコードするときは,URL を書き換えるメソッドと <code>URLEncoder</code> クラスを混同しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://www.owasp.org/index.php/Top_10_2010-A3-Broken_Authentication_and_Session_Management">OWASP Top 10 2010-A3-Broken Authentication and Session Management</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECURLR">URL を書き換えるメソッド</BugCode> <!-- Insecure SMTP SSL connection --> <Detector class="com.h3xstream.findsecbugs.crypto.InsecureSmtpSslDetector"> <Details>安全でない SMTP SSL 接続を検出します。</Details> </Detector> <BugPattern type="INSECURE_SMTP_SSL"> <ShortDescription>安全でない SMTP SSL 接続</ShortDescription> <LongDescription>この SMTP SSL 接続はサーバー証明書を検証しません。</LongDescription> <Details> <![CDATA[ <p> SSL 接続を確立すると,サーバー ID の確認は無効になります。SSL 接続を有効にする電子メールライブラリによっては,デフォルトでサーバー証明書を検証しません。 これは,すべての証明書を信頼することと同じです。サーバーに接続しようとすると,このアプリケーションは "hackedserver.com" に対して発行された証明書をすぐに受け入れます。 アプリケーションは,ハッキングされているサーバーへの不正な SSL 接続によって,ユーザー機密情報を漏洩させる可能性があります。 </p> <p> <b>脆弱なコード:</b><br> <pre>... Email email = new SimpleEmail(); email.setHostName("smtp.servermail.com"); email.setSmtpPort(465); email.setAuthenticator(new DefaultAuthenticator(username, password)); email.setSSLOnConnect(true); email.setFrom("[email protected]"); email.setSubject("TestMail"); email.setMsg("This is a test mail ... :-)"); email.addTo("[email protected]"); email.send(); ...</pre> </p> <p> <b>解決策:</b><br> 次のチェックを追加して,サーバ証明書を確認してください: <pre>email.setSSLCheckServerIdentity(true);</pre> </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/297.html">CWE-297: Improper Validation of Certificate with Host Mismatch</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECISC">安全でない SMTP SSL 接続</BugCode> <!-- AWS Query Injection --> <Detector class="com.h3xstream.findsecbugs.injection.aws.AwsQueryInjectionDetector"> <Details>AWS Query インジェクションを検出します。</Details> </Detector> <BugPattern type="AWS_QUERY_INJECTION"> <ShortDescription>AWS Query インジェクション</ShortDescription> <LongDescription>この SimpleDB クライアントは,信頼できないソースからのデータを受け入れます。</LongDescription> <Details> <![CDATA[ <p> ユーザー入力を含む SimpleDB クエリを構築することにより,攻撃者は権限のないレコードを閲覧できます。<br> 次の例では,ユーザーが productCategory を指定できるようにする SimpleDB <code>select()</code> クエリーを動的に構築して実行します。 攻撃者は,クエリーを変更し,顧客 ID に必要な認証をバイパスし,任意の顧客に一致するレコードを表示できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>... String customerID = getAuthenticatedCustomerID(customerName, customerCredentials); String productCategory = request.getParameter("productCategory"); ... AmazonSimpleDBClient sdbc = new AmazonSimpleDBClient(appAWSCredentials); String query = "select * from invoices where productCategory = '" + productCategory + "' and customerID = '" + customerID + "' order by '" + sortColumn + "' asc"; SelectResult sdbResult = sdbc.select(new SelectRequest(query)); </pre> </p> <p> <b>解決策:</b><br> この問題は SQL インジェクションに似ています。SimpleDB クエリーを使用する前にユーザー入力をエスケープします。 </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/943.html">CWE-943: Improper Neutralization of Special Elements in Data Query Logic</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECAQI">AWS Query インジェクション</BugCode> <!-- JavaBeans Property Injection --> <Detector class="com.h3xstream.findsecbugs.injection.beans.BeanInjectionDetector"> <Details>JavaBeans プロパティインジェクションを検出します。</Details> </Detector> <BugPattern type="BEAN_PROPERTY_INJECTION"> <ShortDescription>JavaBeans プロパティインジェクション</ShortDescription> <LongDescription>JavaBeans プロパティ名には,ユーザーが制御するパラメータが設定されています。</LongDescription> <Details> <![CDATA[ <p> 攻撃者は,システムの完全性を損なう任意の Bean プロパティを設定できます。Bean population 機能は,Bean プロパティまたはネストされたプロパティを設定できます。 攻撃者は,この機能を利用して,class.classLoader のような特別な Bean プロパティにアクセスし,システムプロパティを無効にし,任意のコードを実行させる可能性があります。 </p> <p> <b>脆弱なコード:</b><br> <pre>MyBean bean = ...; HashMap map = new HashMap(); Enumeration names = request.getParameterNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); map.put(name, request.getParameterValues(name)); } BeanUtils.populate(bean, map);</pre> </p> <p> <b>解決策:</b><br> ユーザーが制御する値を使用して Bean のプロパティ名を設定しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/15.html">CWE-15: External Control of System or Configuration Setting</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECBPI">JavaBeans プロパティインジェクション</BugCode> <!-- Struts and Spring File Disclosure --> <Detector class="com.h3xstream.findsecbugs.injection.fileDisclosure.FileDisclosureDetector"> <Details>Struts と Spring の File Disclosure を検出します。</Details> </Detector> <!-- Struts File Disclosure --> <BugPattern type="STRUTS_FILE_DISCLOSURE"> <ShortDescription>Struts File Disclosure</ShortDescription> <LongDescription>ActionForward にユーザーが制御するパラメーターが設定されています。</LongDescription> <Details> <![CDATA[ <p> ユーザー入力を使用してサーバー側のリダイレクトパスを作成すると,攻撃者はアプリケーションバイナリ (アプリケーションクラスまたはjarファイルを含む) をダウンロードしたり保護されたディレクトリ内の任意のファイルを表示できます。<br> 攻撃者は,重要なファイルの場所と一致するリクエストパラメーターを偽造できます。 たとえば, "http://example.com/?returnURL=WEB-INF/applicationContext.xml" を要求すると,アプリケーションの applicationContext.xml ファイルが表示されます。 攻撃者は,他の設定ファイル,クラスファイル,jar ファイルで参照されている applicationContext.xml を見つけてダウンロードし,機密情報を取得して他の種類の攻撃を開始できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>... String returnURL = request.getParameter("returnURL"); Return new ActionForward(returnURL); ...</pre> </p> <p> <b>解決策:</b><br> ユーザーが制御する入力を使用してサーバーサイドリダイレクトを構成しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/552.html">CWE-552: Files or Directories Accessible to External Parties</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSFD">Struts File Disclosure</BugCode> <!-- Spring File Disclosure --> <BugPattern type="SPRING_FILE_DISCLOSURE"> <ShortDescription>Spring File Disclosure</ShortDescription> <LongDescription>ModelAndView にユーザーが制御するパラメータが設定されています</LongDescription> <Details> <![CDATA[ <p> ユーザー入力を使用してサーバー側のリダイレクトパスを作成すると,攻撃者はアプリケーションバイナリ (アプリケーションクラスまたはjarファイルを含む) をダウンロードしたり保護されたディレクトリ内の任意のファイルを表示できます。<br> 攻撃者は,重要なファイルの場所と一致するリクエストパラメーターを偽造できます。 たとえば, "http://example.com/?returnURL=WEB-INF/applicationContext.xml" を要求すると,アプリケーションの applicationContext.xml ファイルが表示されます。 攻撃者は,他の設定ファイル,クラスファイル,jar ファイルで参照されている applicationContext.xml を見つけてダウンロードし,機密情報を取得して他の種類の攻撃を開始できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>... String returnURL = request.getParameter("returnURL"); return new ModelAndView(returnURL); ...</pre> </p> <p> <b>解決策:</b><br> ユーザーが制御する入力を使用してサーバーサイドリダイレクトを構成しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/552.html">CWE-552: Files or Directories Accessible to External Parties</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSF">Spring File Disclosure</BugCode> <!-- RequestDispatcher File Disclosure --> <BugPattern type="REQUESTDISPATCHER_FILE_DISCLOSURE"> <ShortDescription>RequestDispatcher File Disclosure</ShortDescription> <LongDescription>RequestDispatcher にユーザーが制御するパラメーターが設定されています。</LongDescription> <Details> <![CDATA[ <p> ユーザー入力を使用してサーバー側のリダイレクトパスを作成すると,攻撃者はアプリケーションバイナリ (アプリケーションクラスまたはjarファイルを含む) をダウンロードしたり保護されたディレクトリ内の任意のファイルを表示できます。<br> 攻撃者は,重要なファイルの場所と一致するリクエストパラメーターを偽造できます。 たとえば, "http://example.com/?returnURL=WEB-INF/applicationContext.xml" を要求すると,アプリケーションの applicationContext.xml ファイルが表示されます。 攻撃者は,他の設定ファイル,クラスファイル,jar ファイルで参照されている applicationContext.xml を見つけてダウンロードし,機密情報を取得して他の種類の攻撃を開始できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>... String jspFile = request.getParameter("jspFile"); request.getRequestDispatcher("/WEB-INF/jsps/" + jspFile + ".jsp").include(request, response); ...</pre> </p> <p> <b>解決策:</b><br> ユーザーが制御する入力を使用してサーバーサイドリダイレクトを構成しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="https://cwe.mitre.org/data/definitions/552.html">CWE-552: Files or Directories Accessible to External Parties</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECSFDR">RequestDispatcher File Disclosure</BugCode> <!-- Format String Manipulation --> <Detector class="com.h3xstream.findsecbugs.injection.formatter.FormatStringManipulationDetector"> <Details>書式文字列引数でユーザー入力を検出します。</Details> </Detector> <BugPattern type="FORMAT_STRING_MANIPULATION"> <ShortDescription>Format String Manipulation</ShortDescription> <LongDescription>パラメーターのユーザー制御を可能にする書式文字列引数です。</LongDescription> <Details> <![CDATA[ <p> ユーザー入力で書式パラメーターが制御できるようになっていると,攻撃者が例外を投げたり情報を漏らしたりする可能性があります。<br> 攻撃者は,書式文字列の引数を変更して,例外がスローされるようにすることができます。この例外がキャッチされなかった場合,アプリケーションがクラッシュする可能性があります。 あるいは,未使用の引数内で機密情報が使用されると,攻撃者はこの情報を暴露するために書式文字列を変更できます。<br> 次のサンプルコードでは,残高を示す小数点をユーザーが指定できます。実際には,例外がスローされる原因となるものを指定することができ,アプリケーションの障害を引き起こす可能性があります。 この例ではさらに重要なことに,攻撃者がユーザー入力 "2f %3$s %4$.2" を指定できると,書式文字列は "The customer: %s %s has the balance %4$.2f %3$s %4$.2" となります。 これにより,結果文字列に機密の <code>accountNo</code> が含まれることになります。 </p> <p> <b>脆弱なコード:</b><br> <pre>Formatter formatter = new Formatter(Locale.US); String format = "The customer: %s %s has the balance %4$." + userInput + "f"; formatter.format(format, firstName, lastName, accountNo, balance);</pre> </p> <p> <b>解決策:</b><br> 書式文字列引数にユーザーが制御する値を使用しないでください。 </p> <br> <p> <b>参考文献</b><br> <a href="http://cwe.mitre.org/data/definitions/134.html">CWE-134: Use of Externally-Controlled Format String</a><br> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECFSM">Format String Manipulation</BugCode> <!-- HTTP Parameter Pollution --> <Detector class="com.h3xstream.findsecbugs.injection.http.HttpParameterPollutionDetector"> <Details>ユーザー制御下の入力を URL に連結しています。</Details> </Detector> <BugPattern type="HTTP_PARAMETER_POLLUTION"> <ShortDescription>HTTP Parameter Pollution</ShortDescription> <LongDescription>ユーザー制御下の入力を URL に連結しています。</LongDescription> <Details> <![CDATA[ <p> 未検証のユーザー入力を URL に連結すると,攻撃者にリクエストパラメーターの値の上書きを許します。 攻撃者が,既存のパラメーターの値を上書きしたり,新しいパラメーターを挿入したり,直接到達できない変数を利用したりすることができます。 HTTP Parameter Pollution (HPP) 攻撃は,エンコードしたクエリ文字列区切り文字を他の既存のパラメーターに挿入することで成り立ちます。 Web アプリケーションがユーザー入力を適切にエスケープしていないと,悪意のあるユーザーがアプリケーションのロジックを侵害して,クライアント側またはサーバー側の攻撃を実行する可能性があります。<br> 次の例では,プログラマは,攻撃者が <code>en&user_id=1</code> のような <code>lang</code> を指定できる可能性を考慮していないため,攻撃者が思いのままに <code>user_id</code> を変更できます。 </p> <p> <b>脆弱なコード:</b><br> <pre>String lang = request.getParameter("lang"); GetMethod get = new GetMethod("http://www.host.com"); get.setQueryString("lang=" + lang + "&user_id=" + user_id); get.execute();</pre> <p> <b>解決策:</b><br> HTTP パラメータで使用する前にユーザー入力をエスケープします。 </p> <br> <p> <b>参考文献</b><br> <a href="https://capec.mitre.org/data/definitions/460.html">CAPEC-460: HTTP Parameter Pollution (HPP)</a> </p> ]]> </Details> </BugPattern> <BugCode abbrev="SECHPP">HTTP Parameter Pollution</BugCode> </MessageCollection>
© 2015 - 2025 Weber Informatics LLC | Privacy Policy