innerHTMLはテキストだけではなく、HTMLタグも含めて表示したいときに使います。
しかし、もしユーザーの入力をそのまま innerHTML に入れてしまうと、悪意のある人が変なコードを書き込むことで、ページが思わぬ動きをする可能性があります。

これってどういうことなのでしょうか?
今回はinnerHTMLが危険といわれる理由と、安全な扱い方ついてまとめました。

innerHTMLとは?

innerHTMLを使い、値に<b>や<br>を入れると、それらがHTMLタグとして認識されます。
<b>は太字、<br>は改行を表します。

例えば次のコードの場合です。

 result.innerHTML = “<strong>くれび、プログラミングがんばってるよ!</strong>”;

画面には 太字の「くれび、プログラミングがんばってるよ!」が表示されます。

ポイントは、
「文字」ではなく「HTMLとして解釈される」 という点です。

何が問題になるの?

問題になるのは、ユーザーが入力した内容をそのまま innerHTML に入れた場合です。

よくある初心者コード
<input id=”text” type=”text”>
<button onclick=”show()”>表示</button>
<div id=”result”></div>
<script>
  function show() {
    let input = document.getElementById(“text”).value;
    document.getElementById(“result”).innerHTML = input;
  }
</script>

「入力した文字を表示するだけ」
一見すると問題なさそうですよね。

もし次のような入力をされたらどうなるでしょうか。

<script>alert(‘実行されました’);</script>

結果は…
アラートが実行され、「実行されました」というメッセージが表示されます👿

なぜなら innerHTML は、
入力された文字を
「ただの文字」ではなく
HTMLコードとして解釈・実行してしまう からです。

これがなぜ危険なのか?

今回の例はアラートが出るだけですが、実際にはもっと危険なことが可能です。

例えば、
・ログイン情報を盗む
・勝手に別のサイトへ移動させる
・なりすまし投稿をする
などが考えられます。

つまり、
ユーザーに「JavaScriptを書ける場所」を渡してしまっている
状態になる
のです。

このような攻撃を XSS(クロスサイトスクリプティング)と呼びます。

初心者はどう書けば安全?

「文字として表示したいだけ」の場合は、innerHTMLではなくtextContentを使いましょう。

document.getElementById(“result”).textContent = input;

これなら、同じ入力をしても

<script>alert(‘実行されました’);</script> は そのまま文字として表示されるだけで、実行されません。

innerHTMLを使ってもよい場合

innerHTMLは必ずしも使ってはいけないわけではありません。

例えば、次のような場合は問題ありません。
・自分で用意したHTMLだけを表示する
・ユーザー入力を含まない

まとめ

・innerHTMLは便利だがHTMLとして解釈・実行される
・ユーザー入力をそのまま入れると危険
・文字表示ならtextContentを使う
・初心者のうちはinnerHTMLは慎重に使う

innerHTMLの危険性も理解し、正しく使うようにしましょう。