信頼できないソースからのHTMLを高速かつ設定可能にクレンジングするためのライブラリです。Java 7+ に対応しています。
別の言い方をすれば、これは、クライアントがプロフィールやコメントなどでサーバーに永続化されるHTMLに、悪意のあるカーゴコードを混入させないことを保証するのに役立つAPIです。Webアプリケーションにおける「悪意のあるコード」といえば、通常は「JavaScript」を意味します。多くの場合、カスケーディングスタイルシート(CSS)が悪意があると見なされるのは、JavaScriptを呼び出すときだけです。しかし、「通常の」HTMLやCSSが悪意のある方法で使用される状況は数多く存在します。
まず、Mavenから依存関係を追加します:
<dependency>
<groupId>org.owasp.antisamy</groupId>
<artifactId>antisamy</artifactId>
<version>LATEST_VERSION</version>
</dependency>
おそらく、あなたのサイトでのAntiSamyのユースケースは、定義済みのポリシーファイルのいずれかとおおよそ同等でしょう。それぞれが、ユーザーがHTML(および場合によってはCSS)のフォーマット情報を提供することを許可するための「典型的な」シナリオを表しています。それぞれのポリシーファイルを見てみましょう:
Slashdotは、非常に限られたHTMLマークアップでユーザーがニュース投稿に匿名で返信できるようにする、テクノロジー系ニュースサイトです。Slashdotは、最もクールなサイトの一つであるだけでなく、数多くの異なる攻撃の標的にもなってきました。Slashdotのルールはかなり厳格で、ユーザーが送信できるのは次のHTMLタグのみで、CSSは許可されません: <b>、<u>、<i>、、。
<a><blockquote>これに応じて、私たちはほぼ同様の機能を許可するポリシーファイルを構築しました。フォント、色、または強調に直接作用するすべてのテキスト整形タグが許可されています。
eBayは、私の知る限り、世界で最も人気のあるオンラインオークションサイトです。公開サイトであるため、誰でもリッチなHTMLコンテンツを含む出品を投稿できます。eBayが標的として魅力的であることを考えると、いくつかの複雑なXSS攻撃の標的になったのは驚くことではありません。出品には、たとえばSlashdotなどよりもはるかにリッチなコンテンツを含めることが許可されているため、その攻撃対象領域はかなり広いです。
MySpaceは、このプロジェクトが生まれた当時、最も人気のあるソーシャルネットワーキングサイトでした。ユーザーは、JavaScriptを含まない限り、ほぼすべてのHTMLとCSSを送信することが許可されていました。MySpaceはユーザーのHTMLを検証するために単語ブラックリストを使用していたため、悪名高いSamyワームの標的となりました。フラグメンテーション攻撃と、ブラックリストに登録されるべきだった単語(eval)を組み合わせて使用したSamyワームは、このプロジェクトの着想の源です。
このポリシーファイルのユースケースは私にはわかりません。すべての有効なHTMLおよびCSS要素(ただしJavaScriptや露骨なCSS関連のフィッシング攻撃は除く)を許可したい場合は、このポリシーファイルを使用できます。MySpaceでさえ、ここまで奔放ではありませんでした。ただし、すべての要素の基本ルールが含まれているため、他のポリシーファイルを調整する際のナレッジベースとして使用できる、優れたリファレンスとして機能します。
AntiSamyポリシーファイル用のAntiSamyのXMLスキーマ定義(XSD)に対するいくつかの改善に取り組んでいる際、AntiSamyが実際にはXSDを強制していないことに気付きました。そこで、AntiSamy 1.6.0以降、デフォルトの動作を変更し、スキーマを強制し、AntiSamyポリシーが無効な場合は続行しないようにしました。ただし...
開発者がポリシーが非準拠である場合にすぐにAntiSamyポリシーを修正できない可能性があり、それでもセキュリティの改善、機能強化、バグ修正を取り込むためにAntiSamyをアップグレードしたいと考えるかもしれないことを認識しています。そのため、スキーマ検証を(一時的に!)無効にする2つの方法を提供しました:
Javaシステムプロパティ owasp.validator.validateschema をfalseに設定します。これはコマンドライン(例: -Dowasp.validator.validateschema=false)またはJavaシステムプロパティファイルで行うことができます。どちらの場合もコードの変更は必要ありません。
AntiSamyを使用するコードを変更して、AntiSamyポリシーをロードする前に Policy.setSchemaValidation(false) を呼び出します。これは静的呼び出しであるため、一度無効にすると、すべての新しい Policy インスタンスで無効になります。
AntiSamyユーザーにXSD準拠のポリシーのみを使用するよう促すために、AntiSamyはスキーマ検証が無効になっているときは常に何らかの警告をログに記録します。ポリシーが非準拠であるため修正できるようにWARNするか、ポリシーは準拠しているがスキーマ検証がOFFであるため、検証を再度オンにする(つまり、無効化をやめる)ようにWARNします。また、AntiSamyスキーマがロードされ検証されたときにINFOレベルのロギングも追加しました。
新しいスキーマ検証機能を無効にする機能は、適切に有効なAntiSamyポリシーファイルへの移行を円滑にするための一時的なものです。この機能は次のメジャーリリースで削除する予定です。これは2022年の中頃から後半になる見込みで、それほど遠い未来ではありません。目的は、AntiSamyを直接、またはESAPIなどの他のライブラリを通じて使用している開発チームに、スキーマ検証が必須になる前にポリシーファイルをスキーマ準拠にするための十分な時間を提供することです。
これは1.6.1でslf4j APIのみを使用するようにすぐに修正されました。AntiSamyには現在、ロギング用にslf4j-simpleライブラリが含まれていますが、AntiSamyユーザーは必要に応じて代替のslf4j互換ロギングライブラリをインポートして使用できます。また、必要に応じてslf4j-simpleを除外することもできます。
警告: AntiSamyが設定ファイルなしでslf4j-simpleを使用すると、メッセージがバッファリングされて標準出力にログ記録されます。そのため、PolicyException などの例外がスローされた場合、これらのログメッセージの一部またはすべてが失われる可能性があります。これは、slf4j-simpleを標準エラーにログ出力するように設定するか、そうする代替のslf4jロガーを使用することで修正できる可能性があります。
AntiSamyをデフォルト設定でデプロイしたい場合もあるでしょうが、サイトがユーザーに許可する内容に対して厳格なビジネス主導のルールを望む場合も同様にあり得ます。調整を決定する議論では、攻撃対象領域(ポリシーファイルに比例して拡大する)も考慮する必要があります。
AntiSamyの使用は簡単です。ポリシーファイルを使用してAntiSamyを呼び出す例を次に示します:
import org.owasp.validator.html.*;
Policy policy = Policy.getInstance(POLICY_FILE_LOCATION);
AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, policy);
MyUserDAO.storeUserProfile(cr.getCleanHTML()); // 何らかのカスタム関数
Policy オブジェクトを作成するにはいくつかの方法があります。getInstance() メソッドは次のいずれかを受け取ることができます:
String のファイル名File オブジェクトInputStreamPolicy ファイルは、次の例のように AntiSamy#scan() メソッドに2番目の引数を渡すことでもファイル名で参照できます:AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, policyFilePath);
最後に、ポリシーファイルは2番目のパラメータで File オブジェクトとして直接参照することもできます:
AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, new File(policyFilePath));
CleanResults オブジェクトは多くの有用なものを提供します。
getErrorMessages() - Stringのエラーメッセージのリスト -- これが0を返したとしても、攻撃がなかったことを意味するわけではありません!getCleanHTML() - クリーンで安全なHTML出力getCleanXMLDocumentFragment() - getCleanHTML() に反映されるクリーンで安全な XMLDocumentFragmentgetScanTime() - スキャン時間を秒単位で返します重要な注意: getErrorMessages() メソッドについては多くの混乱がありました。getErrorMessages() メソッドは、空のリストを返した場合に「この入力は安全か?」という質問に肯定的に暗に答えるものではありません。常にサニタイズされた入力を使用する必要があり、渡された入力に攻撃がなかったことを確信する方法はありません。
サニタイザーの効果に不可欠なシリアライゼーションおよびデシリアライゼーションプロセスは、意図的にロッシー(情報を失う)であり、多くの攻撃ベクトルを介して攻撃をフィルタリングします。残念ながら、この戦略のトレードオフの1つは、攻撃が発生したことを事後的に常に把握できるとは限らないことです。したがって、getErrorMessages() APIは、開発者が攻撃が存在したかどうかを検出するのに役立つものではなく、ユーザーが意図した入力をシステムの要件に適合させることを理解するのに役立つためにあります。
追加のドキュメントは、このGithubプロジェクトのwikiページで入手できます: https://github.com/nahsra/antisamy/wiki およびOWASP AntiSamyプロジェクトページ: https://owasp.org/www-project-antisamy/
バグを発見した場合は、AntiSamyリポジトリでイシューを作成してください: https://github.com/nahsra/antisamy/issues
AntiSamyに脆弱性を発見した場合は、まずイシューリスト(上記参照)を検索して、既に報告されているかどうかを確認してください。報告されていない場合は、Dave Wichers (dave.wichers at owasp.org) に直接連絡してください。パッチが実装およびデプロイされている間、ユーザーの安全を確保したいため、脆弱性をGitHubのイシューで報告しないでください。脆弱性を発見したことについて謝辞を希望する場合は、このプロセスに従ってください。
詳細はファイルにあります: SECURITY.md。
ソースから簡単にビルドおよびテストできます:
$ git clone https://github.com/nahsra/antisamy
$ cd antisamy
$ mvn package
BSD-3-Clause ライセンスの下でリリースされています。詳細はこちら: LICENSE。