はじめに
※私の根本的な理解が欠けているのだと思います。遠慮なくご指摘いただけると幸いです。
ある本に、以下の記述がありました。
属性値をくくる「"」や「'」は一定のルールのもとで省略が可能です。ただし、状況によってはセキュリティリスク、例えばWebアプリケーションの脆弱性を利用した攻撃であるクロスサイトスクリプティング(XSS)の原因になる場合もあるため、原則として必ず記述することをおすすめします。
-> 「"」を使用することでXSSを防げる、あるいは危険性を低くできる
本当に?
XSSを防げない例
ChatGPTと協力し、以下のコードを作成しました。
<input type="text" id="text_form" placeholder="名前を入力">
<button id="btn">表示</button>
<div id="area"></div>
const text_form = document.getElementById("text_form");
const btn = document.getElementById("btn");
const area = document.getElementById("area");
const output_user_name = () => {
const user_name = document.createElement("p");
user_name.textContent = text_form.value;
user_name.id = text_form.value;
area.append(user_name);
}
btn.addEventListener("click", output_user_name)
問題の箇所は、
user_name.id = text_form.value;
の部分です。これにより、以下のHTML要素が作成されます。
<p id=text_form.value>text_form.value</p>
<!--text_form.valueが「foo」のとき-->
<p id=foo>foo</p>
この入力フォームに対するXSSは、以下の文字列をフォームに入力することで可能です。
""><script>alert('XSS');</script>
これにより、HTML要素が以下の形になり、alert('XSS')
が実行されてしまいます。
<p id=""><script>alert('XSS');</script>>...</p>
"
を用いて XSSを防げる例
const text_form = document.getElementById("text_form");
const btn = document.getElementById("btn");
const area = document.getElementById("area");
const output_user_name = () => {
const user_name = document.createElement("p");
user_name.textContent = text_form.value;
- user_name.id = text_form.value;
+ user_name.id = '"' + text_form.value '"';
area.append(user_name);
}
btn.addEventListener("click", output_user_name)
先程の例に "
を追加しました。
これにより、先程の入力によるXSSは無効化されます。
<p id="""><script>alert('XSS');</script>">...</p>
しかし、この例にはいくつも問題があります。
- JSにおけるコードの改変であり、HTMLの入力において気をつけるべき、という事例には不適当
- 2つめの例であっても、文字列を変更すればXSSは可能
その手間は変わっていないと言える - 現代のブラウザの機能によるものだと思うが、この事例は実際には機能しない
-
"
は自動で"
に変換される -
<script>
タグの中に直接処理が書かれている場合、これを実行しない
-
ですが、これ以上の良い事例を作ることはできませんでした・・・
おわりに
なんとも曖昧な記事で申し訳ないです。
個人的な結論としては以下。