読者です 読者をやめる 読者になる 読者になる

yukata

日々出会ったIT技術関連の所感やら紹介やら

HTMLの属性値はなんでダブルクォートで囲むことが推奨されているのか考えてみた

最近セキュリティの勉強をしています。

その中で一つ疑問に思って色々調べてみたけど、なかなか理由がわからないことがありました。

それは、HTMLの属性値を「"(ダブルクォート)」で囲むことを推奨していることです。

HTMLの属性値は、クライアントから受け取った値を使って動的に生成している場合、クロスサイトスクリプティングの脆弱性が発生してしまいます。そのため、HTMLエスケープする必要がありますが、「'(シングルクォート)」や「"(ダブルクォート)」の引用符で囲まなければ、たとえエスケープしていてもクロスサイトスクリプティングが可能です。

例えば以下のように、攻撃文字列の間にスペースを入れます。

<input type=text name=name value=<?php echo(htmlspecialchars($_GET())); ?>>
↓
<input type=text name=name value=hogehoge onmouseover=alert(1)>

このように、クロスサイトスクリプティングが成立してしまいます。ただ、なぜ「'(シングルクォート)」ではなく、「"(ダブルクォート)」で囲むことが推奨なのかがわかりませんでした。なぜ「'(シングルクォート)」じゃいけないのか・・・



「"(ダブルクォート)」の推奨に関しては、徳丸本とか、その他いろんなところで、そんな感じのことが書いてありました。


この件に関して、私の調査不足かもしれませんが、検索してもなかなかわからなかったので、以下のように推測してみました。


  1. 動的にHTMLの属性値を生成するとき、クロスサイトスクリプティング対策のため、属性値をHTMLエスケープし、且つ「'(シングルクォート)」か「"(ダブルクォート)」で囲む
  2. HTMLをデバッグするときにソースコードを見るが、不必要な文字列までエスケープされてしまうと、デバッグがしにくい
  3. 英語圏では、日常的に文章等に「'(シングルクォート)」が利用されるので、デフォルトでは「<」、「>」、「&」、「"」の必要最小限のみをエスケープするように関数を作成
  4. エスケープ用の関数を利用する際に、デフォルトでは「'(シングルクォート)」がエスケープされていないことを知らずそのまま使ってしまう。そして属性値を囲む引用符にポリシーがないまま開発してしまい、クロスサイトスクリプティングの脆弱性を作ってしまう
  5. そのため、HTMLの属性値は「"(ダブルクォート)」で囲むことを推奨している


と、こんな感じで考えてみました。

なので、「'(シングルクォート)」で囲ってはいけないわけではなく、デザイナーとか、低レベルのプログラマの人とかと連携して開発する場合は、とりあえずHTMLの属性値を「"(ダブルクォート)」で囲むことを徹底させておけば、脆弱性が作り込まれる可能性を少しでも低くできるんじゃないかということです。