【VBA】HTTP通信でWEBスクレイピング5~CSRFトークン~

CSRFトークン

今日も雨ですな。Jimです。どうも✋

 

雨が続く限りブログの更新は続けます。。ん?

はい。ってことで、今回は『CSRFトークン』について書いていく。

前回『Cookieとセッション』の続きね。

一応、HTTP通信でWEBスクレイピングについては最終回。

 

1、前回までのおさらい

第1回:フォームの構造と開発者ツールでフォームの送信内容について確認しました
第2回:GETでログイン画面(送信フォーム)を取得しました
第3回:POSTでフォームを送信してログイン成功画面を取得できました
第4回:セッションIDによってサーバー側でセッションを識別していることを確認しました

Now⇒

前回で少し触れたけれど、今回は『ログイン済みのセッションからのリクエストなら、それで十分なのか?』ってこと。

 

2、Cookieが自動的に送られることによる問題

ブラウザは気を利かせて対象サイトのCookieをリクエストに付けてくれる。

しかしながら。。

もし、貴方が銀行のWEBサイトにログイン状態で、メールに貼付された悪意のある同銀行の偽サイトのリンクを踏んだとしよう。

条件が揃っていればブラウザはCookieを送信してしまう可能性がある。

そうなった場合、銀行のWEBサイトは『自サイトがレスポンスしたフォームから送られたリクエスト?』なんて、そんなことまではわからない。

要は、偽サイトを介して本物の銀行にアクセスできてしまうし、銀行のWEBページもセッションIDのみで管理していたら何処からアクセスされようが同一セッションと認識するでしょう。

したらどうなる?

そこに意図しない口座に送金するフォームがあったとしたら。。。

((((;゚Д゚))))ガクガクブルブル

 

CSRF:Cross-Site Request Forgery(クロスサイト・リクエスト・フォージェリ)

サイト間リクエスト偽造

 

3、CSRFトークンとは?

『2』のような悪意のあるサイト対策のために、サーバーでランダムなトークンを発行しサーバー側でも保持する。

次回のPOSTリクエストで、サーバー側ではセッションIDとトークンが一致していなければ偽物と判断する。

トークンを発行した自サイトでしか判別できない。。という仕組み。

以前からこの記事で使ってるWEBアプリは、これを実装してあります。

 

4、VBAから送ってみる

POSTでフォームを送信する』発行されたトークンではログインできていたが、トークンを意図的に編集して確認してみよう。(※部分でトークンを加工)

Option Explicit

Private Const url As String = "https://bw-rocket.com/http_scraping"
Private Const name As String = "admin"
Private Const pass As String = "1234"


Public Sub login()

    'ログインページのGETリクエスト
    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP")

    http.Open "GET", url & "/login.php", False
    http.setRequestHeader "User-Agent", "Mozilla/5.0"
    http.send


    'レスポンスヘッダからクッキー取得
    Dim setCookie As String
    setCookie = http.getResponseHeader("Set-Cookie")


    'DOMでcsrf属性の値を取得
    Dim doc As Object
    Set doc = CreateObject("HTMLFile")
    doc.body.innerHTML = http.responseText

    Dim csrf As String
    csrf = doc.getElementsByName("_csrf")(0).Value & "aho"    '--※発行されたトークンとは別物にする


    'フォームの内容をPOSTリクエスト
    Dim postData As String
    postData = "_csrf=" & csrf & _
    "&username=" & name & _
    "&password=" & pass

    http.Open "POST", url & "/authenticate.php", False
    http.setRequestHeader "Cookie", setCookie
    http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    http.send postData

    'フォーム送信のレスポンス
    Debug.Print http.responseText

    Set http = Nothing

End Sub

 

↓サーバー側で不正と判断される。

 

5、今回のまとめ

Cookie ⇒ ブラウザが保持していてリクエスト時に送るもの

セッションID ⇒ サーバーがどのセッションなのか識別するもの

CSRFトークン ⇒ サーバーで正規のフォームから送られたリクエストか判断するランダムなトークン

 

 

はい。っと、、まあ、こういうセキュリティがあるWEBサイトもあるわけで、単純にフォームだけ送信できればいいってもんじゃないってこと。

これまでの記事を把握していれば、あとは実際にブラウザで使って確認していけば大体のWEBサイトはスクレイピングできると思う。

そして次回は『WEBAPIを使ってみる』です。

スクレイピングについては、基本的にこの記事でおしまい。

でも、伝えたいことはそこじゃないんだよ。

ってことー✋