pisuke-code.com
Open in
urlscan Pro
210.150.110.215
Public Scan
URL:
https://pisuke-code.com/xss-attack-by-one-line-javascript/
Submission: On June 14 via manual from JP — Scanned from JP
Submission: On June 14 via manual from JP — Scanned from JP
Form analysis
1 forms found in the DOMPOST https://pisuke-code.com/wp-comments-post.php
<form action="https://pisuke-code.com/wp-comments-post.php" method="post" id="commentform" class="comment-form">
<p class="comment-notes"><span id="email-notes">メールアドレスが公開されることはありません。</span> <span class="required">*</span> が付いている欄は必須項目です</p><label for="comment" class="label">Comment</label>
<p class="control"><textarea class="textarea" id="comment" name="comment" placeholder="コメントを入力してください。"></textarea></p><label for="author" class="label">Name<span class="required">*</span></label>
<p class="control"><input class="input" id="author" name="author" type="text" value="" size="30"></p>
<label for="email" class="label">Email<span class="required">*</span></label>
<p class="control"><input class="input" id="email" name="email" type="text" value="" size="30"></p>
<label for="url" class="label">Website</label>
<p class="control"><input class="input" id="url" name="url" type="text" value="" size="30"></p>
<p><img src="https://pisuke-code.com/wp-content/plugins/siteguard/really-simple-captcha/tmp/331619454.png" alt="CAPTCHA"></p>
<p><label for="siteguard_captcha">上に表示された文字を入力してください。</label><br><input type="text" name="siteguard_captcha" id="siteguard_captcha" class="input" value="" size="10" aria-required="true"><input type="hidden" name="siteguard_captcha_prefix"
id="siteguard_captcha_prefix" value="331619454"></p>
<p class="form-submit"><input name="submit" type="submit" id="comment_submit" class="submit" value="コメントを送信"> <input type="hidden" name="comment_post_ID" value="4607" id="comment_post_ID">
<input type="hidden" name="comment_parent" id="comment_parent" value="0">
</p>
<p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="6952ab6e9b"></p>
<p style="display: none !important;"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="1655166391117">
<script>
document.getElementById("ak_js_1").setAttribute("value", (new Date()).getTime());
</script>
</p>
</form>
Text Content
PisukeCode - Web開発まとめ * |エンジニアが使うべき Q&A サイト6選| * |技術系ブログをやるメリット&始め方| * |お問い合わせ| * |プライバシーポリシー| * Home * Web開発 * 【XSS攻撃】JavaScript1行でできるハッキング手順&対策 * 2020/11/18 * 2020/11/14 * PisukeCode - Web開発まとめ 【XSS攻撃】JAVASCRIPT1行でできるハッキング手順&対策 * * * * * ハッキングというと・・・ * 黒い画面に白文字が流れる * 高度なプログラミング知識が必要 * なんかスゴイことをしている こういうイメージがあります。 一部のハッカーはそうかもですが、身近なハッキングだとJavaScript初心者でもできることがあります。(サーバー側で対策が取られていない場合) そこでウェブサービスを開発する人やハッキングを学びたい人に向け、【XSS攻撃】の初歩的な手法&対策について紹介したいと思います。 このページの目次 [隠す] * まずはXSS攻撃の概要について * XSS攻撃による具体的ハッキング手順 * 1.ハッキング対象のサーバーの脆弱性 * 2.XSS攻撃はJavaScript1行だけでもできる * XSS攻撃の基本対策は特殊文字エスケープ! まずはXSS攻撃の概要について XSS攻撃とは何なのか・・・ その説明だけすると次の通りです。 ▼ とりあえずWikipediaから引用 > クロスサイトスクリプティング(英: cross site > scripting)とは、Webアプリケーションの脆弱性[1]もしくはそれを利用した攻撃。脆弱性をツリー型に分類するCWEではこの攻撃を不適切な入力確認(CWE-20)によるインジェクション(CWE-74)のひとつとして分類している(CWE-79)[2]。略称はXSS。かつてはCSSという略称も使われていたが、Cascading > Style Sheetsと紛らわしいのでこの略称はあまり使われなくなった[1]。 > > 引用元 : クロスサイトスクリプティング XSS = cross site scripting Webアプリケーションだと入力フォームとか投稿フォームがあります。そこで悪意のあるコードが埋め込まれることによって、個人情報を引き抜いたり、悪意のあるサイトに飛ばすことが可能です。 とはいえ、これだけだと具体的なイメージが湧きにくいはず。そこで攻撃者側にとってどういうサーバーが好都合なのか、そして具体的なハッキング手法を次で紹介します。 XSS攻撃による具体的ハッキング手順 1.ハッキング対象のサーバーの脆弱性 例えば「6ch」という掲示板サイトがあるとします。 ※ 実在のサイト・団体とは無関係 この 6ch には次の脆弱性が存在していました。 まずはデータべ―ス構成から ▼ 投稿を保存するテーブル構成 カラム名 ID nickname content 説明 一意なID 投稿者名 投稿本文 ものすごく簡易的な掲示板です。 スレッドとかも建てれません。 ただデータべ―スには問題なしです。 そして投稿は次の保存処理で実行しています。 ▼ このようなPHPコードで投稿していた PHP <?php $nickname = $_POST['nickname']; $content = $_POST['content']; if (isset($nickname) && isset($content)) { $sql = " INSERT INTO posts ( nickname, content ) VALUES (?, ?); "; $stmt = $mysqli->prepare($sql); $stmt->bind_param( 'ss', $nickname, $content); $stmt->execute(); $stmt->close(); } ?> <html> <head> <title>6chへようこそ</title> </head> <body> <form action="" method="POST"> <div> <label>お名前 : </label> <input type="text" id="nickname" name="nickname"> </div> <textarea id="content" name="content"></textarea> <button type="submit">送信</button> </form> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php $nickname = $_POST['nickname']; $content = $_POST['content']; if (isset($nickname) && isset($content)) { $sql = " INSERT INTO posts ( nickname, content ) VALUES (?, ?); "; $stmt = $mysqli->prepare($sql); $stmt->bind_param( 'ss', $nickname, $content); $stmt->execute(); $stmt->close(); } ?> <html> <head> <title>6chへようこそ</title> </head> <body> <form action="" method="POST"> <div> <label>お名前 : </label> <input type="text" id="nickname" name="nickname"> </div> <textarea id="content" name="content"></textarea> <button type="submit">送信</button> </form> </body> </html> ここも問題ないですね。 データべ―スに投稿データを保存してるだけです。 問題があったのが 投稿の出力処理 でした・・・ ▼ このように投稿一覧を表示してしまっていた PHP <?php $posts = []; $sql = " SELECT ( nickname, content ) FROM posts "; $stmt = $mysqli->prepare($sql); $stmt->execute(); $stmt->bind_result('ss', $nickname, $content); while($stmt->fetch()){ array_unshift($posts, [ 'nickname' => $nickname, 'content' => $content ]); } $stmt->close(); ?> <html> <head> <title>掲示板</title> </head> <body> <div class="container"> <?php foreach($posts as $post): ?> <div class="post"> <div class="nickname"> <?php echo $post->nickname; ?> </div> <div class="content"> <?php echo $post->content; ?> </div> </div> <?php endforeach; ?> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?php $posts = []; $sql = " SELECT ( nickname, content ) FROM posts "; $stmt = $mysqli->prepare($sql); $stmt->execute(); $stmt->bind_result('ss', $nickname, $content); while($stmt->fetch()){ array_unshift($posts, [ 'nickname' => $nickname, 'content' => $content ]); } $stmt->close(); ?> <html> <head> <title>掲示板</title> </head> <body> <div class="container"> <?php foreach($posts as $post): ?> <div class="post"> <div class="nickname"> <?php echo $post->nickname; ?> </div> <div class="content"> <?php echo $post->content; ?> </div> </div> <?php endforeach; ?> </div> </body> </html> これはかなりヤバいコードです。 何がマズいかというと、 echo $post->nickname; みたいに直出力してることですね。もし投稿画面から悪意のあるデータを送れば、次のイタズラ・犯罪ができるって訳です。 * 悪意あるサイトに閲覧者を飛ばす * 閲覧者の個人情報を抜き取る * 不正ソフトをダウンロードさせる ではこの架空の6chをハッキングしてみます。 2.XSS攻撃はJAVASCRIPT1行だけでもできる その方法は驚くほど簡単です。 例えばウィルスサイトに閲覧者を飛ばすとします。 その場合、掲示板に次の内容を書き込むだけ ▼ 投稿本文に次を書いて送信 XHTML <script> location.href = "http://googkle.com/"; </script> 1 2 3 <script> location.href = "http://googkle.com/"; </script> ▼ 実際はこういうイメージ はい、たったこれだけです。 正直言ってJavaScript初心者でもできます。 普通、こんな初歩的なハッキング(XSS攻撃)は通用しないです。でも世の中探せば、こんな脆弱性たっぷりのサービスも案外あるかもしれませんね・・・(-_-;) 攻撃者側はセキュリティの強いサイト・サービスは狙わないらしいです。むしろ容易に突破できる安全意識の低い場所を狙うと思います。(自分がクラッカーだった場合) XSS攻撃の基本対策は特殊文字エスケープ! XSS攻撃の対策は難しくありません。 出力時にHTML特殊文字をエスケープするだけです。 PHPだとhtmlspecialchars関数が使えます。 ▼ 公式リファレンスでの解説 > htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, > string $encoding = ini_get("default_charset") [, bool $double_encode = TRUE > ]]] ) : string > > 文字の中には HTML において特殊な意味を持つものがあり、 それらの本来の値を表示したければ HTML の表現形式に変換してやらなければなりません。 > この関数は、これらの変換を行った結果の文字列を返します。 > > 引用元 : https://www.php.net/manual/ja/function.htmlspecialchars.php ▼ この関数の実用的な使い方 PisukeCode - Web開発まとめ PHPでhtmlspecialchars関数をh()で省略する書き方&注意点 https://pisuke-code.com/php-define-htmlspecialchars-as-h PHPにはXSS攻撃を防ぐ関数が用意されてます。それがあの htmlspecialchars 関数手軽にHTML特殊文字をエスケープできて便利です、ただ便利なんですが・・・正直言って長い(笑)そこで少しでも効率化するために、この htmlspecialchars() を h() で定義する方法を紹介します。まずhtmlspecialchars関数の意味と使い方から・・まずhtmlspecialchars関数について。PHPにおいては、こういう役割があります。▼ htmlspecialchars関数の解説htmlspecialchars ( string $string ]] ) : string文字の中には HTML において特殊な意味を持つものが... 詳しくは上記事などをご覧ください。 XSS攻撃は出力時さえ気を付ければ大丈夫ですね。 以上、JS1行でできるハッキング手順&対策でした。 関連記事 * PHPからストリーム出力して Ajax でリアルタイム更新する * Data URLスキームとは何なのか?便利な理由と扱うときの注意点 * Sublime Textでマークダウンをプレビューするのに便利なプラグイン * PHP、JavaScriptでの正規表現の表し方と違いまとめ * Windowsエクスプローラの 応答なし を一発で治す対処法 * Windows環境で.htaccessが作成できないときの超簡単な対処法 * Digital Oceanの使い方 ~ Webアプリ公開までの基本手順【2019最新】 * PHP・JavaScriptそれぞれでリダイレクトさせる方法&コード例まとめ Web開発 SHAREこの記事をシェアしよう! * いいね * ツイート * はてブ * Pocket * 送る ぴー助 個人でWebサービスとかツールとかを開発しているWeb系の人。このブログでは学んだことや開発に役立つ知識、プログラマーや開発者向けの情報を発信していく予定。PHP、JavaScript(jQuery)、CSSがメイン。座右の銘 : 遊びは仕事、仕事は遊び COMMENTSこの記事についたコメント コメントを残す コメントをキャンセル メールアドレスが公開されることはありません。 * が付いている欄は必須項目です Comment Name* Email* Website 上に表示された文字を入力してください。 Δ このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。 プロフィール ぴー助 個人でWebサービスとかツールとかを開発しているWeb系の人。このブログでは学んだことや開発に役立つ知識、プログラマーや開発者向けの情報を発信しています。眉毛が太い ▼ ココナラでCSS相談とかもやってます 招待コード : 4nn62b 人気記事 * jQueryで $ is not define エラーが出たときの一番簡単な解決法 * 【JavaScript】blocked by CORS policy エラーの簡単な解決法 * JavaScriptで配列から値指定で要素削除する2つの方法 * * * JavaScriptで日付(Date)をフォーマットする3つの方法 * jQueryでイベントが発火しないときの簡単な対処法 * 【CSS】枠線を要素内側に引くための3つの方法 * JavaScriptでブラウザバックを “ほぼ完全禁止” する方法 * MySQLで LEFT JOIN でサブクエリが必要な場面とSQL例 * 【CSS】テーブル内の文字列を簡単に折り返す方法 * JavaScriptでJSONファイルをローカルから読み込みするには カテゴリー * HTML * Web開発 * エンジニアの能力向上 * MySQL * AngularJS * Webとかアプリの雑学色々 * Apache・htaccess関連 * SSH・サーバー関係 * フィンテックとか金融とか * Node.js * Androidアプリ開発 * 副業とかビジネスのアレコレ * アプリ・サービスの紹介 * 動画とか画像とかのAPI関連 * Three.js * AWS(Amazon Web Services) * プログラミングの学び方 * Fabric.js * Laravel * Python * 未分類 * JavaScript * jQuery * PHP * CSS * WordPress * * SHAREこの記事をシェアしよう! * いいね * ツイート * はてブ * Pocket * 送る プロフィール ぴー助 個人でWebサービスとかツールとかを開発しているWeb系の人。このブログでは学んだことや開発に役立つ知識、プログラマーや開発者向けの情報を発信しています。眉毛が太い カテゴリー * HTML * Web開発 * エンジニアの能力向上 * MySQL * AngularJS * Webとかアプリの雑学色々 * Apache・htaccess関連 * SSH・サーバー関係 * フィンテックとか金融とか * Node.js * Androidアプリ開発 * 副業とかビジネスのアレコレ * アプリ・サービスの紹介 * 動画とか画像とかのAPI関連 * Three.js * AWS(Amazon Web Services) * プログラミングの学び方 * Fabric.js * Laravel * Python * 未分類 * JavaScript * jQuery * PHP * CSS * WordPress 人気記事 * Weekly * Monthly * Total * jQueryで $ is not define エラーが出たときの一番簡単な解決法 2019.1.18 * 【JavaScript】blocked by CORS policy エラーの簡単な解決法 2019.10.19 * jQueryでイベントが発火しないときの簡単な対処法 2018.9.25 * JavaScriptで配列から値指定で要素削除する2つの方法 2020.9.30 * JavaScriptで日付(Date)をフォーマットする3つの方法 2019.1.7 * 【CSS】枠線を要素内側に引くための3つの方法 2018.11.21 * JavaScriptでブラウザバックを “ほぼ完全禁止” する方法 2020.2.11 * 【CSS】テーブル内の文字列を簡単に折り返す方法 2018.9.8 * MySQLで LEFT JOIN でサブクエリが必要な場面とSQL例 2019.6.29 * 一意な重複しないIDを生成するNG方法と正しい方法 2019.9.9 * jQueryで $ is not define エラーが出たときの一番簡単な解決法 2019.1.18 * 【JavaScript】blocked by CORS policy エラーの簡単な解決法 2019.10.19 * JavaScriptで配列から値指定で要素削除する2つの方法 2020.9.30 * JavaScriptで日付(Date)をフォーマットする3つの方法 2019.1.7 * jQueryでイベントが発火しないときの簡単な対処法 2018.9.25 * 【CSS】枠線を要素内側に引くための3つの方法 2018.11.21 * JavaScriptでブラウザバックを “ほぼ完全禁止” する方法 2020.2.11 * MySQLで LEFT JOIN でサブクエリが必要な場面とSQL例 2019.6.29 * 【CSS】テーブル内の文字列を簡単に折り返す方法 2018.9.8 * JavaScriptでJSONファイルをローカルから読み込みするには 2020.10.14 * jQueryで $ is not define エラーが出たときの一番簡単な解決法 2019.1.18 * 【CSS】枠線を要素内側に引くための3つの方法 2018.11.21 * jQueryでイベントが発火しないときの簡単な対処法 2018.9.25 * JavaScriptで日付(Date)をフォーマットする3つの方法 2019.1.7 * JavaScriptでブラウザバックを “ほぼ完全禁止” する方法 2020.2.11 * PHPからJavaScriptをスマートに呼び出す2つの方法 2018.9.15 * Windowsエクスプローラの 応答なし を一発で治す対処法 2019.5.24 * JavaScriptでデータをJSONに変換したり戻したりする方法まとめ 2018.10.26 * MySQLで LEFT JOIN でサブクエリが必要な場面とSQL例 2019.6.29 * 【JavaScript】blocked by CORS policy エラーの簡単な解決法 2019.10.19 最新の投稿 * Android画面をPCから直接画像キャプチャ・録画する方法 2022.06.08 * 【Laravel】guzzlehttpにてself signed certificateエラーの対処法 2022.06.01 * 【Android】KotlinからRestAPIを数行コードで呼び出し!Fuelを使ってみた 2022.05.25 * Three.jsのオブジェクト移動をTransformControlsで実装【マウス・タッチ両方対応】 2022.05.18 * JavaScriptで入れ子オブジェクトの全要素をループ・全て表示させる 2022.05.12 * Android Studio “emulator-5554 unauthorized” エラーの解決策 2022.05.10 * JavaScript配列への reduce() の使いどころ・実用例をいくつか紹介 2022.05.04 * 【Android】 エミュレータのhostsファイルを編集する方法【xamppのvirtulahost許可】 2022.04.27 * 【JavaScript】setIntervalを停止させたり再開させる方法・コード例 2022.04.20 * JavaScriptでの forループ vs forEach の速度的な違いを検証してみた 2022.04.14 © 2022 PisukeCode – Web開発まとめ