「4.5「重要な処理」の際に混入する脆弱性」について

119 views
Skip to first unread message

OK

unread,
Feb 26, 2025, 12:29:18 PMFeb 26
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。

「4.5「重要な処理」の際に混入する脆弱性」の「3.CSRFの罠(iframe版)」について1点質問(黄色の吹き出し)がございますので、何卒ご回答お願いできますでしょうか。
質問するに当たり、私の認識を図解しております。

何卒よろしくお願い致します。
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
Feb 26, 2025, 10:10:34 PMFeb 26
to wasbook...@googlegroups.com
徳丸です。こんにちは。

事象から見て、Firefoxのトータルクッキー保護が働いているように思います。実習環境の準備時に、トータルクッキー保護の無効化をお願いしています。

実習環境のトップの先頭に「(設定をお願いします)Firefoxのトータルクッキー保護導入に伴う設定変更」というものがあります。これがない場合は実習環境が古いです。

あるいは、以下のページにも同内容が掲載されています。




2025年2月27日(木) 2:29 OK <cs00...@gmail.com>:
--
このメールは Google グループのグループ「「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには wasbook-reade...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/296084eb-679c-4212-aa32-af7dfec18712n%40googlegroups.com にアクセスしてください。


--

OK

unread,
Feb 27, 2025, 10:23:16 AMFeb 27
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。

主題の件、ご回答ありがとうございます。
トータルクッキー保護を無効化したことで、正常に動作するようになりました。
あまり詳細を理解できていませんが勉強を続けます。

今後ともよろしくお願い致します。

2025年2月27日木曜日 12:10:34 UTC+9 徳丸浩:

OK

unread,
Mar 4, 2025, 12:00:48 PMMar 4
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。

「4.5「重要な処理」の際に混入する脆弱性」の「4.パスワード変更CSRF対策版(正常系)」について2点質問(黄色の吹き出し)がございますので、何卒ご回答お願いできますでしょうか。(質問吹き出しはP.13~P.15)
質問するに当たり、私の認識を図解しております。

何卒よろしくお願い致します。

2025年2月28日金曜日 0:23:16 UTC+9 OK:
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
Mar 6, 2025, 12:42:46 AMMar 6
to wasbook...@googlegroups.com
徳丸です。こんにちは。

【質問1】下記条件②で防げるCSRF攻撃は攻撃者がどのルートで攻撃することを前提としていますでしょうか。
②[$p_token]と[$s_token]が異なる

これは、攻撃者が正規の入力画面ではなく、攻撃者が独自に作った入力画面から攻撃するという前提です。独自に作った入力画面では、正しいCSRFトークンがわかりませんので、トークンを空にするか、勝手に作ったトークンを入れるしかありません。勝手に作ったトークンの場合に、上記②の状況になります。

【質問2の続き】このif文の場合トークン有無に関わらず[$token]および[$_SESSION[‘token’]]は同じ値になる気がします。CSRF攻撃されたと判断できる条件[$p_token !== $s_token]
はどのようなケースで発生しますでしょうか?

これも質問1と同じ状況です。
そもそも、CSRF攻撃というのは、入力画面は攻撃者が勝手に作るものです。ここの理解ができてないのだと思います。利用者の入力画面を勝手に操作することは一般的にはできません。なので、他所のサイトで攻撃者が勝手に作った罠からの攻撃をするのがCSRFです。





2025年3月5日(水) 2:00 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/a31f4561-0f29-4148-bade-6bf13cb83953n%40googlegroups.com にアクセスしてください。


--

岡慎一郎

unread,
Mar 7, 2025, 2:59:10 AMMar 7
to wasbook...@googlegroups.com
徳丸様、いつもお世話になっております。
追加で質問させてください。 

【質問1】 
「攻撃者が独自に作った入力画面から攻撃するという前提」は、 徳丸本の検証環境の「5.パスワード変更CSRF対策 版(攻撃)」がそれに当たりますでしょうか。(以下、「攻撃環境」と記載します。) 

【質問2】
 攻撃環境を検証したところ、WEBブラウザ →example.jp(A)へのhttpリクエストに[token]がありませんでした。([pwd]はPOSTされている)
攻撃環境の場合、私がお送りしたスライドP.14の[$p_tokenが空]の条件に合致して、CSRF攻撃されていると判断した、という認識で合ってますでしょうか。 

【質問3】
【質問2】が正しい場合、攻撃環境のrap.example.comでは[token」を発行していないということでしょうか。

【質問4】
一般的な攻撃者が用意した罠サイトで[token]を発行している場合のCSRF攻撃を防ぐために、【②[$p_token]と[$s_token]が異なる]の条件が設けられている、ということでしょうか。
②の条件がない場合、①の条件([$p_token]が空でない)だけではCSRF攻撃された判定できない、と認識しました。


2025年3月6日(木) 14:42 徳丸浩 <htok...@gmail.com>:
このメールは Google グループのグループ「「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML」のトピックを登録しているユーザーに送られています。
このトピックの登録を解除するには https://groups.google.com/d/topic/wasbook-readers/2phr2Wn4WcE/unsubscribe にアクセスしてください。
このグループを退会し、グループのすべてのトピックの登録を解除するには wasbook-reade...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/CANJDpr8MA684%2Bzc_KOtFDcUKXbiu4oBWFeOkj4c%2B_ai51hmZLw%40mail.gmail.com にアクセスしてください。

徳丸浩

unread,
Mar 7, 2025, 4:20:09 AMMar 7
to wasbook...@googlegroups.com
徳丸です。こんにちは。

【質問1】 「攻撃者が独自に作った入力画面から攻撃するという前提」は、 徳丸本の検証環境の「5.パスワード変更CSRF対策 版(攻撃)」がそれに当たりますでしょうか。(以下、「攻撃環境」と記載します。) 

はい、そのとおりです。

【質問2】
 攻撃環境を検証したところ、WEBブラウザ →example.jp(A)へのhttpリクエストに[token]がありませんでした。([pwd]はPOSTされている)
攻撃環境の場合、私がお送りしたスライドP.14の[$p_tokenが空]の条件に合致して、CSRF攻撃されていると判断した、という認識で合ってますでしょうか。 

はい、そのとおりです。

【質問3】
【質問2】が正しい場合、攻撃環境のrap.example.comでは[token」を発行していないということでしょうか。

発行していません。発行することもできますが、正しいものはわからないので、一致性のチェックでエラーになります。

【質問4】
一般的な攻撃者が用意した罠サイトで[token]を発行している場合のCSRF攻撃を防ぐために、【②[$p_token]と[$s_token]が異なる]の条件が設けられている、ということでしょうか。
②の条件がない場合、①の条件([$p_token]が空でない)だけではCSRF攻撃された判定できない、と認識しました。

どちらかというと、②の方が対策の本命なのですが、②だけだとトークンが空の場合に対応できないので①もあるという感じです。
必ずセッション変数の方にtoken($s_token)があるような実装だと、②だけでも行ける場合もあります(推奨はしませんが)。

2025年3月7日(金) 16:59 岡慎一郎 <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/CAA_5hecD3vL%2BZ3AouM%2B%3D-O2-XCyGWnGxyM1Laad9C%2BFOB3HXZg%40mail.gmail.com にアクセスしてください。


--

岡慎一郎

unread,
Mar 7, 2025, 4:52:26 AMMar 7
to wasbook...@googlegroups.com
徳丸様、いつもお世話になっております。
ご回答ありがとうございました。
大変勉強になりました。

引き続き、勉強を続けます。
今後ともよろしくお願い致します。

2025年3月7日(金) 18:20 徳丸浩 <htok...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/CANJDpr9h0FKoBi6Bo1058%3DvikW%3DY5C8tDntCJ7m-ssB9MLBiSw%40mail.gmail.com にアクセスしてください。

岡慎一郎

unread,
Mar 8, 2025, 2:08:06 AMMar 8
to wasbook...@googlegroups.com
徳丸様、いつもお世話になっております。
追加で質問させてください。

【質問1】
徳丸本P.193
「45-003a.php【トークン確認の例(実行画面)】」の3行目の「empty ($_session [‘token’])」ですが、
検証環境と合わせて評価するならば、この条件は
「empty ($token)」ではないでしょうか?

45-002a.php、または攻撃者が用意した罠サイト
からPOSTされたトークンが空かどうかを判定する、という目的であれば、
「empty ($token)」と思いました。
検証環境は上記の条件でした。

【質問2】
徳丸本P.194の3行目の「セッション変数にトークンがセットされていない状況」とは、「攻撃者が用意した罠サイトからPOSTされた状況」ということでしょうか?

【質問3】
徳丸本P.194の3行目の「このチェックがないと」とは、下記のようなif文になっているという意味でしょうか?
if($token!==$_session [‘token’])

お忙しいところ恐れ入りますが、何卒よろしくお願い致します。

2025年3月7日(金) 18:52 岡慎一郎 <cs00...@gmail.com>:

徳丸浩

unread,
Mar 9, 2025, 8:06:12 AMMar 9
to wasbook...@googlegroups.com
徳丸です。こんにちは。

> 【質問1】
>  徳丸本P.193
>  「45-003a.php【トークン確認の例(実行画面)】」の3行目の「empty ($_session [‘token’])」ですが、
>  検証環境と合わせて評価するならば、この条件は「empty ($token)」ではないでしょうか?
> 45-002a.php、または攻撃者が用意した罠サイトからPOSTされたトークンが空かどうかを判定する、という目的であれば、「empty ($token)」と思いました。
>  検証環境は上記の条件でした。

ここの処理は、POSTパラメータとして受け取ったトークン(PTとします)とセッション変数のトークン(STとします)が一致しているかというチェックですが、以下3点の条件があります。

(1) PTが空でない
(2) STが空でない
(3) PTとSTが等しい

ところが、書籍および実習環境は2つの条件のみをチェックしています。その理由は、(1)と(3)あるいは(2)と(3)のチェックで十分だからです。
たとえば、(1)と(3)ですと、PTが空でなく、PTとSTは等しいことから結局STも空でない、すなわち(2)も成り立つことが分かります。(2)と(3)の場合も同様です。
経験豊富なプログラマだとこのあたりの条件は考えなくても直感的に分かってしまうものですが、敢えて3条件をチェックしてもよいわけで、そうしないまでも上記を説明した方が親切でしたね。

また、書籍の執筆にあたって、該当箇所の初稿では以下のようになっていました。

$p_token = fileter_input(INPUT_POST, 'token');
$s_token = @$_SESSION['token'];
if ( empty( p_token) || $p_token !== s_token )
  // エラー処理

これは現在の実習環境と同じです。@はエラー制御演算子と呼ばれるものです。これがある理由は、$_SESSION['token']がセットされていない場合に警告が表示されてしまうので、その警告を消すためです。
ただ、エラー制御演算子はあまり良くない書き方とされていて、これを使わないためには、事前に$_SESSION['token']がセットされているかを確認することになります。そのリファクタリングをしたのが、現行の書籍版の書き方です。

$token = filter_input(INPUT_POST, 'token');
if (empty($_SESSION['token']) || $token !== $_SESSION['token']) {
  // エラー処理

つまり、empty($_SESSION['token']) のチェックは、$_SESSION['token']の中身にアクセスする前に、本当に値が入っているかをチェックするためです。それが「トークンがセッション変数にセットされているか」とちょうど重なるので、こう書いた方がプログラムが簡潔になり、エラー制御演算子を使わなくて済むという判断からこうなっています。書籍と実習環境で差異があるのは、実習環境側の修正もれです。申し訳ありません。

>  【質問2】
>   徳丸本P.194の3行目の「セッション変数にトークンがセットされていない状況」とは、「攻撃者が用意した罠サイトからPOSTされた状況」ということでしょうか?

そのケースが大半だとは思いますが、このふたつの状況はイコールではないですね。「セッション変数にトークンがセットされていない状況」になる例としては、セッション変数が一旦セットされたものの時間経過によりセッションタイムアウトを起こしたとか、別タブでログアウトボタンを押したのでセッションが消去された状況なども含まれます。


>  【質問3】
>   徳丸本P.194の3行目の「このチェックがないと」とは、下記のようなif文になっているという意味でしょうか?
>   if($token!==$_session [‘token’])

書籍の該当箇所は以下のようになっています。

> ここで、empty()によりトークンが空でないことを確認していますが、これは重要な確認で
> す。このチェックがないと、セッション変数にトークンがセットされていない状況で、hidden
>  パラメータのトークンがなくても処理が継続されてしまいます。

日本語的には、「このチェック」は直前の「empty()によりトークンが空でないことを確認」を指しています。すなわち、empty($_SESSION['token'])を指します。
文意としても、「このチェックがないと、セッション変数にトークンがセットされていない状況で、hidden パラメータのトークンがなくても処理が継続されてしまいます。」なので、トークンの存在チェック、すなわちempty関数の呼び出しを指すことになります。


2025年3月8日(土) 16:08 岡慎一郎 <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/CAA_5hedhrsZDXkanNEFXG0_%3DH9DjnuCdWZF56JwbqHGiHSc0ew%40mail.gmail.com にアクセスしてください。


--

OK

unread,
Mar 16, 2025, 6:49:21 AMMar 16
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
ご回答ありがとうございました。

添付にて別の内容ですが質問させて頂けますでしょうか。
お忙しい所恐れ入りますが、何卒よろしくお願い致します。

2025年3月9日日曜日 21:06:12 UTC+9 徳丸浩:
補足資料【認証画面(正常系)】.pdf
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
Mar 16, 2025, 10:29:00 AMMar 16
to wasbook...@googlegroups.com
徳丸です。こんにちは。

> 【質問1】この内容では、ログイン部分が簡略化されていますでしょうか。

はい。簡略化というより省略されている感じですね。

> 【質問2】【質問1】が正しい場合、上記赤四角は添付の補足資料でしょうか。

いいえ、「例えば」という意味であればその通りですが、それに限りません。なにかしらのログイン処理ということです。

> 【質問3】ここでは実際に何が実行されていますしょうか。補足資料の手順10~12と予想しております。

ここは「なにか重要な処理」ですので、それに限りません。典型的には更新処理です。



2025年3月16日(日) 19:49 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/88b60369-dd1f-4301-9552-9f3775c2fad1n%40googlegroups.com にアクセスしてください。


--

OK

unread,
Mar 16, 2025, 11:43:57 AMMar 16
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
ご回答ありがとうございました。
大変勉強になりました。

引き続き、勉強を続けます。
今後ともよろしくお願い致します。

2025年3月16日日曜日 23:29:00 UTC+9 徳丸浩:

OK

unread,
Mar 19, 2025, 1:50:54 PMMar 19
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。

「4.5「重要な処理」の際に混入する脆弱性」の「5.パスワード変更CSRF対策版(攻撃)」を勉強するにあたり、下記の2パターンを考えてみました。

・「example.jp」にログインしていない状態のCSRF攻撃
→添付ファイルのP.1~11
→質問をP.9に記載

・「example.jp」にログインされた状態のCSRF攻撃
→添付ファイルのP.12~17
→質問をP.16に記載

上記2点の質問(黄色の吹き出し)がございますので、何卒ご回答お願いできますでしょうか。
質問するに当たり、私の認識を図解しております。

owasp zapを使用して、セッション変数や$p_tokenの中身を確認する手段はありませんでしょうか。
これが可能になれば、学習が進むように思います。

大変長文で恐縮ですが、何卒よろしくお願い致します。

2025年3月17日月曜日 0:43:57 UTC+9 OK:
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
Mar 20, 2025, 5:55:50 AMMar 20
to wasbook...@googlegroups.com
徳丸です。こんにちは。

>【質問1】[45-002a.php]未経由のためセッション変数が空→下記条件のためCSRF攻撃されていると判断可能
>         ①[$_SESSION['token']]が空という認識で合ってますでしょうか。


はい、サンプルプログラムを動かせばそうなりますが、そもそもの前提として、攻撃対象のプログラムはパスワード変更の機能であり、ログイン済みであることの確認が本来はあります。サンプルプログラムでは、以下のようにコメントされている部分です。

// ログイン確認…省略

なので、実際のアプリケーションでは、この「ログイン確認」で「未ログインです」などのエラーになる、あるいは単にログイン画面にリダイレクトされるなどの挙動になり、CSRFチェックまで処理が進むことはありません。


>【質問2】罠サイトではトークン未発行のため[$p_token]が空→下記条件のためCSRF攻撃されていると判断可能という認識で合ってますでしょうか。
>    ②[$p_token]と[$_SESSION['token']]が不一致

はい、その通りです。
しかし、実際の攻撃はさまざまなパターンが考えられますが、すべてのケースのサンプルを作成することは紙面の都合上難しいため、代表例のみが載っております。このサンプルの作り方だと、ログイン直後はトークンがセッション変数になく、パスワード変更の入力画面でトークンをセットしているため、「ログインしているがセッション変数にトークンはない」という状況も、現実のアプリケーションを想定するとありえます。その場合は、empty($_SESSION['token'])の方で弾かれることになります。


> owasp zapを使用して、セッション変数や$p_tokenの中身を確認する手段はありませんでしょうか。
> これが可能になれば、学習が進むように思います。

OWASP ZAPではプログラム内部の変数やセッション変数を確認することはできません。それができてしまうと重大なセキュリティ上の問題になります。
変数等の確認の方法の例としては、①PHP用のデバッガを使用する、②サンプルプログラム上の値を確認したいところに、var_dump($p_session); など値を表示する処理を追加する(printデバッグ、あるいはvar_dumpデバッグなどと呼ばれます)方法があります。


2025年3月20日(木) 2:51 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/b77b657f-635c-417b-a309-bb64f80ef545n%40googlegroups.com にアクセスしてください。


--

OK

unread,
Mar 21, 2025, 6:27:00 AMMar 21
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
ご回答ありがとうございました。
大変勉強になりました。

引き続き、質問させて頂けますでしょうか。
P.2,8,9に質問を三点記載致しました。

お忙しい所恐れ入りますが、何卒よろしくお願い致します。

2025年3月20日木曜日 18:55:50 UTC+9 徳丸浩:
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
Mar 21, 2025, 7:34:27 AMMar 21
to wasbook...@googlegroups.com
徳丸です。こんにちは。

【質問1】この部分は具体的にどのような動作をしているのでしょうか。

これは、ウェブでファイルアップロード等に使われるmultipart/form-dataという形式をJavaScriptで作っているところです。HTMLのフォームではファイル名やファイルの中身は利用者のみが指定でき、HTML等では指定できませんが、HTTPリクエストボディをJavaScriptで作ることにより、ファイル名やファイルの中身を利用者を介さないで指定するものです。

multipart/form-dataの説明はChatGPTに作ってもらいましたので添付します。
以下、ChatGPTの回答引用

HTTPリクエストの multipart/form-data は、フォームの各入力項目を個別の「パート」に分けて送信する形式で、特にファイルアップロードやテキストデータとファイルデータの混在を送信する際に用いられます。各パートは独自のヘッダーを持ち、どのデータがどのフィールドに対応するかを明示します。

基本構造

  • 境界文字 (Boundary):
    リクエスト全体を複数の部分に分割するための区切り文字列です。HTTPヘッダーの Content-Typeboundary パラメータとして設定され、リクエストボディ内ではこの文字列で各パートが区切られます。

  • 各パートのヘッダー:
    各パートには最低限、以下のようなヘッダーが含まれます。

    • Content-Disposition: どのフォームフィールドに対応するか、またはファイル名などを指定します。
    • Content-Type: そのパートのデータのMIMEタイプを示します(ファイルの場合に特に重要)。

具体例

以下は、ユーザー名と画像ファイルを送信するフォームを例にしたHTTPリクエストの一部です。

POST /upload HTTP/1.1
Host: example.com Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Length: [全体のバイト数] ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="username" john_doe ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="profile_picture"; filename="photo.jpg" Content-Type: image/jpeg [ここにJPEG画像のバイナリデータが入ります] ------WebKitFormBoundary7MA4YWxkTrZu0gW--

説明

  1. リクエストヘッダー:

    • Content-Type ヘッダーにて multipart/form-data と境界文字が指定されています。
    • リクエスト全体の長さは Content-Length により明示されます。
  2. 最初のパート(usernameフィールド):

    • 境界文字で始まり、Content-Disposition: form-data; name="username" と記述。
    • 続く空行の後に実際の値 (john_doe) が記述されています。
  3. 2つ目のパート(ファイルアップロード):

    • 同じく境界文字で区切られ、Content-Disposition でフォームフィールド名(ここでは profile_picture)とファイル名(photo.jpg)が指定されます。
    • Content-Type にはファイルのMIMEタイプ(ここでは image/jpeg)が指定され、空行の後にファイルのバイナリデータが配置されます。
  4. 終了:

    • 最後のパートの後に、境界文字の後ろに -- を付けてリクエストの終了を示します。

この形式を利用することで、サーバー側は各パートごとにデータを解析し、テキストデータとバイナリデータを適切に処理することが可能になります。

------------------ 引用終わり


【質問2】この内容がhttpレスポンスに載っておりますがWEBブラウザに何も表示されないのはなぜでしょうか。

JavaScriptからリクエストした結果のレスポンスですが、以下の理由により表示されません。

(1) レスポンスを表示する処理を書いていない
(2) 仮に(1)の処理を書いたとしても、CORSのエラーによりエラーになるので表示できない


【質問3】本ケースでは、[example.jp/45/img/a.php]の本来の画像から別の画像に差し替えられた、という攻撃、という認識で合っますでしょうか。

違います。a.phpをアップロードした後で、このa.phpを表示すると、拡張子がphpなのでPHPスクリプトとして実行され、その結果を見ていることになります。






2025年3月21日(金) 19:27 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/751f4b29-b5da-432e-9fb5-3558093a5490n%40googlegroups.com にアクセスしてください。


--

OK

unread,
Mar 30, 2025, 11:36:42 AMMar 30
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
返事が遅くなり申し訳ありません。
ご回答ありがとうございました。

【質問2のご回答】
>JavaScriptからリクエストした結果のレスポンスですが、以下の理由により表示されません。

>(1) レスポンスを表示する処理を書いていない
>(2) 仮に(1)の処理を書いたとしても、CORSのエラーによりエラーになるので表示できない
→添付ファイルP.21のように、httpレスポンスを表示するHTMLが記載されてますので、
 (2)のCORSのエラーにより表示されないということですね。

引き続き、質問させて頂けますでしょうか。
P.20に質問を3点記載致しました。
【質問3のご回答】についても質問しております。

お忙しい所恐れ入りますが、何卒よろしくお願い致します。

2025年3月21日金曜日 20:34:27 UTC+9 徳丸浩:
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
Mar 30, 2025, 9:47:53 PMMar 30
to wasbook...@googlegroups.com
徳丸です。こんにちは。

> 【質問1】XMLHttpRequestを受け取ったWEBブラウザが[Origin]と[Referer]を同時に設定しているのでしょうか。

XMLHttpRequestの処理を実行する際にブラウザがOriginとRefererの両ヘッダーを設定しています。


> 【質問2】Referer欄にPOST元のURLが書籍の下記と異なっているのはなぜでしょうか。
http://trap.example.com/45/45-902.html

ブラウザのReferrer-Policyの仕様変更によるものです。

no-referrer-when-downgrade(従来のデフォルト値)
  ↓ 変更
strict-origin-when-cross-origin (現在のデフォルト値)

詳しくは以下を参照ください。

https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Referrer-Policy


> 【質問3】[a.php]と[<?php phpinfo;]を「テキストベースで紐づけている」と認識したのですが合っていますでしょうか。

「テキストベースで紐づけている」の意味がわからないのですが、この箇所が意味するところは、以下のとおりです。

ファイル名: a.php
ファイルの種類(Content-Type): text/plain
ファイルの内容: <?php phpinfo();

利用者がa.phpというファイル名を指定する→ブラウザが拡張子からContent-Typeを設定し、ファイルの内容はファイルから取得する、という流れです。


それと、以下は間違いです。

> →添付ファイルP.21のように、httpレスポンスを表示するHTMLが記載されてますので、
> (2)のCORSのエラーにより表示されないということですね。

このHTTPレスポンスは、JavaScriptのXMLHttpRequestに対する応答なので、JavaScript側でレスポンスを表示する処理を書かないと表示されません。確かにCORSのエラーは発生していますが、仮にエラーがなくても、表示処理がないので表示されません。
表示処理というのは、33-005.html(P186)を例にすると、req.onreadystatechange = function() { 以下の処理です。罠のスクリプトにはこの部分がありません。表示してもエラーになるだけなので書いていないということです。

<body>
<script>
  var req = new XMLHttpRequest();
  req.open('GET', 'http://api.example.net/33/33-006.php');
  req.onreadystatechange = function() {                  // 表示処理の指定
      if (req.readyState == 4 && req.status == 200) {
         var span = document.getElementById('counter');
        span.textContent = req.responseText;
      }
  };
  req.send(null);
</script>
呼び出しカウンター:<span id="counter"></span>
</body>



2025年3月31日(月) 0:36 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/d06bb1dc-34e7-425b-a730-44f7c5e8b01cn%40googlegroups.com にアクセスしてください。


--

OK

unread,
Apr 13, 2025, 12:15:30 PMApr 13
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
返事が遅くなり申し訳ありません。
ご回答ありがとうございました。

> →添付ファイルP.21のように、httpレスポンスを表示するHTMLが記載されてますので、
> (2)のCORSのエラーにより表示されないということですね。
→こちらについてもご指摘ありがとうございます。
 [45-005.php]→WEBブラウザへのhttpレスポンスのbody内がWEBブラウザに表示されると勘違いしておりました。body内はXMLHttpRequestへの応答と理解しました。その後、JavaScript側でWEBブラウザに表示する処理(req.onreadystatechangeなど)がないのでWEBブラウザに表示されないと理解しました。

今後ともよろしくお願い致します。

2025年3月31日月曜日 10:47:53 UTC+9 徳丸浩:

OK

unread,
May 18, 2025, 12:07:23 PMMay 18
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
「4.5「重要な処理」の際に混入する脆弱性」の「3.クリックジャッキングの罠」を勉強するにあたり、3点質問させてください。
P.4,6に質問を3点記載致しました。

お忙しい所恐れ入りますが、何卒よろしくお願い致します。

2025年4月14日月曜日 1:15:30 UTC+9 OK:
「重要な処理」の際に混入する脆弱性.pdf

徳丸浩

unread,
May 19, 2025, 12:49:17 AMMay 19
to wasbook...@googlegroups.com
徳丸です。こんにちは

> 【質問①】今回の例では、このテキストエリアは特に使われていないでしょうか。罠サイト内の投稿ボタンがクリックされなければ、テキストエリアの文字列はPOSTされないため

このtextaearは機能としては使われていませんが、その下のボタンの位置合わせのために置いてあります。攻撃対象とボタンの位置を合わせるには、元と同じHTMLであれば、ブラウザ等が変わっても同じ位置になることが確実になるためです。
仮にtextareaを置かないと、ボタンの位置を数値で指定することになりますが、数値指定だと異なるブラウザで試すと意外に位置がずれたりしたので、この方式にしました。

> 【質問②】罠サイト内の投稿ボタンはクリックされることはないでしょうか。この後、透明の攻撃対象ページが手前に表示されるため

そのとおりです。見た目としてのボタンは必要なので置いてあります。

> 【質問③】攻撃対象ページを表示するiframeの不透明度が[0.5]になっているのはなぜでしょうか。手前側に表示するため、[0](透明)にすべきと思いました。

攻撃のためにはその通りですが、このスクリプトは攻撃の説明用なので半透明にしました。結局ラジオボタンで指定しているので、こちらの設定は無視された格好になっていますが。


2025年5月19日(月) 1:07 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/9eb5a6e3-7ea5-4c6d-8556-a07b0d57b2d3n%40googlegroups.com にアクセスしてください。


--

OK

unread,
May 21, 2025, 10:56:33 PMMay 21
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
ご回答ありがとうございます。

【質問③】のご回答についてですが、再度質問させてください。
iframeタグ実行時に[opacity=0.5(半透明)]を設定したが、
その後のscriptでの[wana.style.opacity=0.0(透明)]が効いて、罠サイトの手前に表示されたiframe(攻撃対象WEBページが表示されている)が透明になった、という認識で合ってますでしょうか。

何卒よろしくお願い致します。

2025年5月19日月曜日 13:49:17 UTC+9 徳丸浩:

徳丸浩

unread,
May 21, 2025, 11:16:49 PMMay 21
to wasbook...@googlegroups.com
徳丸です。こんにちは。

> 【質問③】のご回答についてですが、再度質問させてください。
> iframeタグ実行時に[opacity=0.5(半透明)]を設定したが、
> その後のscriptでの[wana.style.opacity=0.0(透明)]が効いて、罠サイトの手前に表示されたiframe(攻撃対象WEBページが表示されている)が透明になった、という認識で合ってますでしょうか。

はい、合っています。



2025年5月22日(木) 11:56 OK <cs00...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/wasbook-readers/9b97a3c5-e3de-4f79-a7d3-0f8f7fe4cc62n%40googlegroups.com にアクセスしてください。


--

OK

unread,
Jun 2, 2025, 12:49:38 PMJun 2
to 「体系的に学ぶ 安全なWebアプリケーションの作り方」サポートML
徳丸様、いつもお世話になっております。
ご回答ありがとうございます。

今後ともよろしくお願い致します。

2025年5月22日木曜日 12:16:49 UTC+9 徳丸浩:
Reply all
Reply to author
Forward
0 new messages