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

Form analysis 1 forms found in the DOM

POST 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開発まとめ