JavascriptのXSS対策として以前アドバイス頂いたようにinnerHTMLでHTMLのエスケープ処理コードを書いてみたのですが、正しいのか分かりませんアドバイスお願い致します。
Document.createTextNodeを代用する方法もアドバイス頂いたので考えてみたのですが、使い方が難しく既存のHTMLにあっているのか心配です…
※アドバイス頂いた質問
https://oshiete.goo.ne.jp/qa/13578040.html
※名前HTML
<div class="msg_partial">あと<strong>50</strong>文字</div>
※コメントHTML
<div class="msg_partial">あと<strong>500</strong>文字</div>
※該当コード
<h2>名前<span class="required">※必須</span></h2>
<input class="length_input" data-maxlength="<?php echo MAX_LENGTH::NAME; ?>" type="text" name="namae" id="name" placeholder="未入力の場合は、匿名で表示されます" value="<?php echo $namae; ?>">
<div class="msg_partial"></div>
<h2>コメント<span class="required">※必須</span></h2>
<textarea class="length_input" data-maxlength="<?php echo MAX_LENGTH::MESSAGE; ?>" name="message" id="message" placeholder="荒らし行為や誹謗中傷や著作権の侵害はご遠慮ください"><?php echo $message; ?></textarea>
<div class="msg_partial"></div>
※エスケープ処理を追加
function lengthCheck() {
const left = this.dataset.maxlength - this.value.length;
if (left >= 0) {
const a = document.querySelectorAll('msg_partial');
return a.innerHTML;
this.nextElementSibling.innerHTML = '<strong>' + escapeHTML(left) + '</strong>文字';
this.dataset.submit_disabled = this.value.length === 0;
} else {
const b = document.querySelectorAll('msg_partial');
return b.innerHTML;
this.nextElementSibling.innerHTML = '<strong>' + escapeHTML(-left) + '</strong>文字超過しています';
this.dataset.submit_disabled = true;
}
_________________________________________________________
※Document.createTextNodeを利用したもの
<script>
function lengthCheck(text) {
const newtext = document.createTextNode(text);
msg_partial = document.querySelectorAll("msg_partial");
const left = this.dataset.maxlength - this.value.length;
if (left >= 0) {
this.nextElementSibling.innerHTML = 'あと<strong>' + addTextNode('left') + '</strong>文字';
this.dataset.submit_disabled = this.value.length === 0;
} else {
this.nextElementSibling.innerHTML = '<strong>' + addTextNode('-left') + '</strong>文字超過しています';
this.dataset.submit_disabled = true;
}
msg_partial.appendChild(newtext);
}
</script>
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
セキュリティ云々以前の問題として、動くかどうかデバッグ確認をしましょう。
いまのままでは「コードのように見えるなにか」でしかないので評価以前の問題です。XSS の根本的解決とは、「全て」の出力をエスケープすることです。
これはつまり、入力値ではないとか仕様上不可能とかの理由でエスケープ有無を都度判断することなく、文字通り全ての出力をエスケープすることを求めています。
参考) 安全なウェブサイトの作り方 - 3.5.2 対策漏れ
https://www.ipa.go.jp/security/vuln/websecurity/ …
もしエスケープしない出力が残っていると、その時点では問題がない値だったとしても、今後の仕様変更にて問題のある値が入り込み、それなのにエスケープを忘れる単純ミスを犯した場合、脆弱性が生まれてしまいます。
そのような人為的なミスまで防止するのが、根本的解決の「全て」に込められた意味です。
参考) fool proof
https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%BC …
innerHTML の代用案ですが、最近のブラウザですと createTextNode の他にも便利な API があるので活用しましょう。
https://developer.mozilla.org/ja/docs/Web/API/El …
https://developer.mozilla.org/ja/docs/Web/API/El …
これらは内部的にエスケープ処理をするので根本的解決たり得ます。
例)
ふ = document.createElement("rt"); ふ.append("うちわ");
季 = document.createElement("ruby"); 季.append("団扇", ふ);
詠 = document.createElement("small"); 詠.append("子規");
書換要素.replaceChildren("ことごとく", 季, "破れし熱さ哉", 詠);
回答ありがとうございます、どうしても分からないのでアドバイスお願い致します。
document.createElementをどのように使えばよいのか分からず困っているのですが、デフォルトで名前(50文字)とメッセージ(500文字)それぞれ上限にした状態で、文字を入力するたびに残り〇文字、〇文字超過と表示させるにはどうすればいいのでしょうか?
※名前HTML
<div class="msg_partial">あと<strong>50</strong>文字</div>
※コメントHTML
<div class="msg_partial">あと<strong>500</strong>文字</div>
※以前教えて頂いたエスケープ方法
function escapeHTML(値) {
var a = document.createElement('span');
a.textContent = 値;
return a.innerHTML;
}
要素.innerHTML = '<strong>' + escapeHTML(文字列) + '</strong>';
No.1
- 回答日時:
前の質問で同様に回答されていた方がいましたがinnerHTMLで使っているのは関数内で代入した数値leftだけですよね?
それで何を心配しているのかハッキリしません。
またnewtext はtextareaの内容をそのまま設定しているように見えますが、それは意図したものでしょうか?
究極的にはブラウザはクライアント側でどうでにでも制御できるものです。
デバッガでスクリプトを一時停止して、本来あり得ない値に書き換えることも可能です。
ウェブサイトは、ブラウザ経由であろうがなかろうが、どんなリクエストをされても
サーバや他のクライアントに害を及ぼさないように作る必要があります。
そこに立ち戻って考えてはどうでしょうか。
A.回答ありがとうございます、innerHTML を使う場合は、問題のない値しか使わないと分かっていたとしても、HTMLのエスケープ処理を行った方がセキュリティ上良いとアドバイスを頂いたためコードを追加いたしました。
デザインを優先した際にPHPとJavascriptを使って実現可能なコードがinnerHTMLかDocument.createTextNodeになると思いますので、現在のコードに合う対策を練るのがベストだと考えております。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript JavascriptでDom XSSの脆弱性対策を行いたい 2 2023/09/24 21:20
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- JavaScript JavascriptでDOM-based XSSの発生源となるinnerHTMLを変更したい 2 2023/08/29 22:11
- JavaScript javascriptとPHPで入力フォームのコードを書いているのですが、 流れとしては、①入力フォー 2 2021/12/02 09:18
- JavaScript 付属の写真のようにエラーが出るようにしたいです。 提示したコードだけでは、エラーメッセージ文字が上の 1 2021/11/23 08:27
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- HTML・CSS CSSが効かずどのように指定すれば良いか分からないのでアドバイスお願い致します 2 2023/06/07 12:25
- JavaScript 【JavaScript】検索がヒットした場合、プルダウンをオープンで表示させる方法 2 2023/09/06 14:02
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
クリッカブルマップと位置を固...
-
formのsubmitを押すとモーダル...
-
CSSでreadonlyの機能はあり...
-
javascript htmlの追記について
-
ドラッグによるスライド移動を...
-
スクリプト初心者なのですが、
-
jQueryのCSSで値に変数を使う方法
-
JavascriptでDom XSSの脆弱性対...
-
3重のクォーテーション
-
改行をしたいが、<br>と...
-
JavaScriptの空欄に埋めるもの...
-
JavaScriptのinnerHTMLの挙動に...
-
確認ダイアログを次からは表示...
-
macかwinか判別しスタイルシー...
-
mouseoverで、リンクをずらす。
-
VBAでCOPYを繰り返すと、処理が...
-
「ご処理進めて頂きますようお...
-
エクセルVBAで、MsgBox やInput...
-
エクセルで、日付を入力すると...
-
「PC Helpsoft Driver Updated...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
動画の上に広告をオーバーレイ...
-
CSSでreadonlyの機能はあり...
-
jQueryでのドラッグアンドドロ...
-
formのsubmitを押すとモーダル...
-
Q&A掲示板の入力フォームに文字...
-
jqueryを使ったスムーススクロ...
-
確認ダイアログを次からは表示...
-
javascriptで複数の表示・非表...
-
javascriptのエラーで質問です。
-
特定の条件のHTML要素を一括で...
-
macかwinか判別しスタイルシー...
-
【JavaScript】検索がヒットし...
-
jQueryのSlickで矢印アイコンが...
-
javascriptでの(-)ハイフンの処...
-
クリックすると、色が変わるよ...
-
時間帯によってclass名を変更し...
-
フォームで「パスワード(確認...
-
3重のクォーテーション
-
SITEINFOの書き方について
-
【至急!!】Jqueryを使った下記...
おすすめ情報