web-dev-qa-db-ja.com

正しく使用された場合、htmlspecialcharsはすべてのXSSに対する保護に十分ですか?

次の記述が当てはまる場合、

  • すべてのドキュメントは、HTTPヘッダー_Content-Type: text/html; charset=UTF-8_で提供されます。
  • すべてのHTML属性は、一重引用符または二重引用符で囲まれています。
  • ドキュメントに_<script>_タグはありません。

htmlspecialchars($input, ENT_QUOTES, 'UTF-8')(_&_、_"_、_'_、_<_、_>_を対応する名前付きHTMLエンティティに変換する場合はありますか? WebサーバーでHTMLを生成するときに、クロスサイトスクリプティングから保護するのに十分ではありませんか?

17
Alf Eaton

htmlspecialchars()は、指定した制限付きでドキュメント作成時のHTMLインジェクションを防ぐのに十分です(つまり、タグコンテンツ/引用符で囲まれていない属性へのインジェクションはありません)。

ただし、XSSにつながる可能性のある他の種類の注入があります。

ドキュメントに<script>タグはありません。

この状態は、JS注射のすべてのケースをカバーするわけではありません。たとえば、イベントハンドラー属性がある場合があります(HTMLエスケープ内にJSエスケープが必要です)。

_<div onmouseover="alert('<?php echo htmlspecialchars($xss) ?>')"> // bad!
_

または、さらに悪いことに、javascript:リンク(JSエスケープがURL内でエスケープする必要があります-HTMLエスケープ内でエスケープする必要があります):

_<a href="javascript:alert('<?php echo htmlspecialchars($xss) ?>')"> // bad!
_

とにかくこれらの構造を避けるのが通常は最善ですが、特にテンプレートを作成するときはそうです。 <?php echo htmlspecialchars(urlencode(json_encode($something))) ?>を書くのはかなり面倒です。

そして...インジェクションの問題はクライアント側でも発生する可能性があります(DOMXSS)。 htmlspecialchars()は、明示的なエスケープなしでinnerHTML(通常は貧弱なjQueryスクリプトでは.html())にJavaScriptが書き込まれるのを防ぎません。

そして... XSSには、注射だけでなく、さまざまな原因があります。その他の一般的な原因は次のとおりです。

  • 正常なURLスキームをチェックせずに、ユーザーがリンクを作成できるようにします(_javascript:_は最もよく知られている有害なスキームですが、他にもあります)

  • ユーザーが直接またはライトマークアップスキーム(常に悪用可能なbbcodeなど)を介してマークアップを作成できるようにする

  • ユーザーがファイルをアップロードできるようにします(さまざまな方法でHTMLまたはXMLとして再解釈できます)

18
bobince

古いPHPバージョン(5.2程度)を使用していないと仮定すると、htmlspecialcharsは「安全」です(もちろん、@ Royal Bgが言及しているようにバックエンドコードを考慮に入れています)

古いPHPバージョンでは、この関数を脆弱にする不正な形式のUTF-8文字がありました( http://www.securityfocus.com/bid/37389

私の2セント:すべてをエスケープ/すべてをエンコードするのではなく、許可されているものを伝えることによって、常に入力をサニタイズ/チェックします

つまり、誰かが電話番号を入力する必要がある場合、次の文字が許可されていると想像できます:0123456789()+-。とスペースですが、他のすべては無視/削除されます

アドレスなどにも同じことが当てはまります。アドレスのドット/ブロック/ハートなどにUTF-8文字を指定している人は精神的に病気である必要があります...

2
Ronald Swets