web-dev-qa-db-ja.com

JSFでのCSRF、XSS、およびSQLインジェクション攻撃の防止

MySQLをDBとしてJSFで構築されたWebアプリケーションがあります。アプリケーションでCSRFを防ぐためのコードを既に実装しています。

基礎となるフレームワークがJSFであるため、XSS攻撃はUIComponentによって既に処理されているため、XSS攻撃を処理する必要はないと思います。ビューページでJavaScriptを使用していません。使用しても、XSS攻撃を防ぐためにコードを実装する必要は本当にありますか?

DBでは、すべてのDBインタラクションで準備済みステートメントとストアドプロシージャを使用しています。

これら3つの一般的な攻撃を防ぐために、他に対処する必要があるものはありますか?私はすでに [〜#〜] owasp [〜#〜] サイトとその cheat sheet を通り抜けました。

他の潜在的な攻撃ベクトルに注意する必要がありますか?

54
AngelsandDemons

XSS

JSFは、組み込みのXSS防止を持つように設計されています。安全にallユーザー制御入力(リクエストヘッダー(Cookieを含む!)、リクエストパラメーター(DBに保存されているものも!) JSFコンポーネントを使用したリクエスト本文(アップロードされたテキストファイルなど)。

_<h:outputText value="#{user.name}" />
<h:outputText value="#{user.name}" escape="true" />
<h:inputText value="#{user.name}" />
etc...
_

FaceletsでJSF 2.0を使用している場合、テンプレートテキストで次のようにELを使用できることに注意してください。

_<p>Welcome, #{user.name}</p>
_

これも暗黙的にエスケープされます。ここでは必ずしも_<h:outputText>_は必要ありません。

Only_escape="false"_を使用してユーザー制御入力を明示的にunescapingしている場合:

_<h:outputText value="#{user.name}" escape="false" />
_

その後、潜在的なXSS攻撃の穴があります!

_<b>_、_<i>_、_<u>_などのHTMLタグの特定のサブセットのみを許可するHTMLとしてユーザー制御入力をHTMLとして再表示する場合は、ホワイトリストによる入力のサニタイズ。 HTMLパーサー Jsoup は、非常に 役に立つ です。

itemLabelEscaped Mojarraのバグ<2.2.6

以前のMojarraバージョンbefore2.2.6には、_<f:selectItems itemLabel>_の代わりに_List<T>_を使用して_<f:selectItems var>_を提供したときに、_List<SelectItem>_が誤ってラベルをエスケープしないバグがありました(SOMECODE)__または_SelectItem[]_を値として( issue 314 )。言い換えると、_List<T>_を介してアイテムラベルとしてユーザー制御データを再表示する場合、潜在的なXSSホールがあります。少なくともMojarra 2.2.6へのアップグレードがオプションではない場合、itemLabelEscaped属性をtrueに明示的に設定して、それを防ぐ必要があります。

_<f:selectItems value="#{bean.entities}" var="entity" itemValue="#{entity}"
    itemLabel="#{entity.someUserControlledProperty}" itemLabelEscaped="true" />
_

CSRF

JSF 2.xは、サーバー側の状態保存を使用する場合、フォームの_javax.faces.ViewState_隠しフィールドのフレーバーにCSRF防止を既に組み込みました。 JSF 1.xでは、この値は非常に弱く、予測しやすいものでした(実際、CSRF防止を意図したものではありませんでした)。 JSF 2.0では、かなり予測可能なシーケンス値の代わりに長くて強力な自動生成値を使用することでこれが改善され、堅牢なCSRF防止になりました。

JSF 2.2では、クライアント側の状態の保存が有効になっている場合に、クライアント側の状態を暗号化するための構成可能なAESキーとともにJSF仕様の必須部分にすることで、さらに改善されます。 JSF仕様の問題869 および 他のセッションでのViewState値の再利用(CSRF) も参照してください。 JSF 2.2の新機能は、 _<protected-views>_ によるGETリクエストのCSRF保護です。

_<f:view transient="true">_のようにステートレスビューを使用している場合、またはアプリケーションにXSS攻撃の穴がある場合にのみ、潜在的なCSRF攻撃の穴があります。


SQLインジェクション

これはJSFの責任ではありません。これを防ぐ方法は、使用している永続性API(未加工のJDBC、最新のJPA、または旧式のHibernate)に依存しますが、すべてを要約する必要がありますneverユーザー制御入力をSQL文字列に連結します

_String sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = md5(" + password + ")";
String jpql = "SELECT u FROM User u WHERE u.username = '" + username + "' AND u.password = md5('" + password + "')";
_

エンドユーザーが次の名前を選択するとどうなるか想像してみてください。

_x'; DROP TABLE user; --
_

該当する場合は、パラメータ化されたクエリをalways使用する必要があります。

_String sql = "SELECT * FROM user WHERE username = ? AND password = md5(?)";
String jpql = "SELECT u FROM User u WHERE u.username = ?1 AND u.password = md5(?2)";
_

プレーンJDBCでは、パラメータ値を入力するために PreparedStatement を使用する必要があり、JPA(およびHibernate)では、 Query オブジェクトがセッターを提供しますこれも同様です。

106
BalusC

ビューページでJavaScriptを使用していません。 doを使用しても、XSS攻撃をバイパスするコードを実装する必要があります。

ページでJavaScriptを使用しない場合でも、XSSに対して脆弱である可能性があります。 XSSは、攻撃者によって制御されたコンテンツを適切にエンコードせずに組み込むと発生します。

いつでもあなたは

response.write("<b>" + x + "</b>")

攻撃者がxにJavaScriptを含むHTMLを含めることができる場合、XSSに対して脆弱です。

通常、解決策は大量のコードを作成しないことです。通常、解決策は、$xおよび攻撃者が制御するその他の値を、生成するHTMLに含める前にエンコードすることです。

response.write("<b>" + escapePlainTextToHtml(x) + "</b>")

入力のフィルタリングまたはサニタイズは、保護の追加レイヤーを提供するのに役立ちます。

<shameless-plug>

XSSから保護するために、出力を自動的にエンコードするテンプレート言語を使用することもできます。

Closure Template は、Javaのそのようなオプションの1つです。

コンテキスト自動エスケープは、クロージャーテンプレートを拡張して、表示されるコンテキストに基づいて各動的値を適切にエンコードし、攻撃者によって制御される値のXSS脆弱性から保護することにより機能します。

編集

JSFを使用しているため、 JSFでのXSS緩和 について読む必要があります。

出力テキストをエスケープする

<h:outputText/>および<h:outputLabel/>のデフォルトでは、エスケープ属性がTrueに設定されています。このタグを使用して出力を表示することにより、XSS脆弱性の大部分を軽減できます。

SeamT​​extParserおよび<s:formattedText/>

ユーザーがいくつかの基本的なhtmlタグを利用して入力をカスタマイズできるようにしたい場合、JBoss Seamはユーザーが指定したいくつかの基本的なhtmlタグとスタイルを許可する<s:formattedText/>タグを提供します。

8
Mike Samuel