XSS、SQL インジェクション、および関連する攻撃を防ぎながら、FCKeditor やその他のエディターのようなエディター (stackoverflow のように) にコード スニペットを入力できるようにするにはどうすればよいでしょうか。
4 に答える
ここでの問題の一部は、特定の種類の HTML を許可したいということですよね? たとえばリンク。ただし、script タグのような XSS 攻撃を含む可能性のある HTML タグだけをサニタイズする必要があります。さらに言えば、イベント ハンドラー属性、href、または「javascript:」で始まるその他の属性も含めてサニタイズする必要があります。したがって、質問に対する完全な回答は、「特殊文字を置き換える」よりも洗練されたものである必要があります。これではリンクが許可されないためです。
SQL インジェクションの防止は、プラットフォームの選択に多少依存する場合があります。私の好みの Web プラットフォームには、クエリをパラメータ化するための構文が組み込まれており、SQL インジェクション (cfqueryparam と呼ばれる) をほとんど防ぐことができます。PHP と MySQL を使用している場合は、同様のネイティブ mysql_escape() 関数があります。(PHP関数が技術的にパラメーター化されたクエリを作成するかどうかはわかりませんが、データベースに安全に保存されたいくつかを見たので、これまでのところSQLインジェクションの試みを防ぐのにうまく機能しています。)
XSS 保護では、このような理由で正規表現を使用して入力をサニタイズしていましたが、リンクなどを許可すると同時に危険なコードを削除することが難しいため、その方法から離れました。代替手段として移行したのは XSLT です。繰り返しになりますが、XSL 変換の実行方法は、プラットフォームによって異なる場合があります。これを行う方法について、ColdFusion Developer's Journalに少し前に記事を書きました。この記事には、使用できるボイラープレート XSL シートと、ネイティブの XmlTransform() 関数を使用して CF で動作させる方法が含まれています。
このために XSLT に移行することを選択した理由は 2 つあります。
最初に、入力が整形式の XML であることを検証することで、特定の文字列連結トリックを使用した XSS 攻撃の可能性を排除します。
次に、生の文字列操作用に設計された正規表現と比較して、構造化された XML ドキュメントで動作するように特別に設計されているため、正規表現を使用するよりも、XSL および XPath セレクタを使用して XHTML パケットを操作する方が簡単です。そのため、よりクリーンで簡単になり、間違いを犯す可能性が低くなり、間違いに気付いた場合でも修正が容易になります。
また、それらをテストしたところ、CKEditor (彼は F を削除した) などの WYSIWYG エディターが整形式の XML を保持することがわかったので、潜在的な問題としてそれについて心配する必要はありません。
保護にも同じ規則が適用されます: フィルター入力、エスケープ出力。
コードを含む入力の場合、フィルタリングは、文字列に印刷可能な文字が含まれている必要があり、おそらく長さ制限があることを意味します。
テキストをデータベースに保存するときは、クエリ パラメーターを使用するか、文字列をエスケープして、SQL インジェクションの脆弱性を引き起こす文字が含まれないようにします。コードにはより多くの記号や英字以外の文字が含まれる場合がありますが、SQL インジェクションに関して注意する必要があるものは通常のテキストと同じです。
正しいエスケープ関数を複製しようとしないでください。ほとんどのデータベース ライブラリには、エスケープが必要なすべての文字を正しくエスケープする関数が既に含まれています (たとえば、これはデータベース固有の場合があります)。また、文字セットに関する特別な問題も処理する必要があります。ライブラリが提供する関数を使用するだけです。
「ストアド プロシージャを使用してください」と人々が言う理由がわかりません。ストアド プロシージャは、SQL インジェクションに対して特別な保護を提供しません。エスケープされていない値を SQL 文字列に補間して結果を実行すると、SQL インジェクションに対して脆弱になります。アプリケーション コードで実行するか、ストアド プロシージャで実行するかは問題ではありません。
Web プレゼンテーションに出力するときは、テキストの場合と同様に、HTML 特殊文字をエスケープします。
SQL インジェクション攻撃を防ぐためにできる最善のことは、データベース呼び出しを行うときにパラメーター化されたクエリまたはストアド プロシージャを使用することです。通常、基本的な入力サニタイズも実行することをお勧めしますが、ユーザーからのコードを受け入れる必要があるため、それはオプションではない可能性があります。
反対に (ユーザーの入力をブラウザーにレンダリングする場合)、データを HTML エンコードすると、悪意のある JavaScript などがクライアントのブラウザーで実行されるのではなく、リテラル テキストとしてレンダリングされます。適切な Web アプリケーション サーバー フレームワークには、この機能が備わっている必要があります。
すべての < を < などに置き換えて (たとえば、PHP で htmlentities を使用)、安全なタグをある種のホワイトリストで選択できると思います。問題は、ホワイトリストが少し厳しすぎることです。
これがPHPの例です
$code = getTheCodeSnippet();
$code = htmlentities($code);
$code = str_ireplace("<br>", "<br>", $code); //example to whitelist <br> tags
//One could also use Regular expressions for these tags
SQL インジェクションを防ぐために、すべての ' および \ 文字を、\' や \ のような「無害な」同等のものに置き換えることができます。これにより、次の C 行が
#include <stdio.h>//'); Some SQL command--
データベースに否定的な結果はありません。