3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

クロスサイトリクエストフォージェリ(CSRF)とは?

Posted at

「クロスサイトリクエストフォージェリ(CSRF)」とは

CSRF(クロスサイトリクエストフォージェリ)とは、Cross-Site Request Forgeriesの略で、別のサイトを通して(クロスサイト)、悪意のある要求(リクエスト)を正しい要求だと偽って(フォージェリ)を送信することです。
##CSRFの原理
image.png
上の図から、1回CSRFの攻撃をするなら、
1、信用サイトAにログインして、cookieを生成します。
2、Aサイトを閉じてないまま、危険サイトBに訪問します。
二つ要素が必要です。

危険性

CSRF脆弱性を具体例を用いて説明する。
今ある銀行のWebサイト(標的サイト)にログインしているユーザALICEが自身の口座からBOBという別のユーザの口座に100ドルを送金する際、ALICEのブラウザから

//bank.com/transfer.do?acct=BOB&amount=100 HTTP/1.1
```というHTTPリクエストが銀行のWebサイトに向かって送信されるものとする。
攻撃者MARIAは
```http://bank.com/transfer.do?acct=MARIA&amount=10000 HTTP/1.1
```というURLを公開掲示板に張ったり、不特定多数にメールしたりする。
銀行のユーザALICEがこのURLをクリックしてしまうと、ALICEのブラウザから
```GET http://bank.com/transfer.do?acct=MARIA&amount=10000 HTTP/1.1
```というHTTPリクエストが銀行に向かって送信される[7]。この際たまたまALICEが銀行にログインしていたら、銀行のサーバはこのリクエストを送金要求だと解釈してしまい、ALICEの口座からMARIAの口座に一万ドルが不正送金されてしまう。


## 対策
***1、http referer***
Referer が正しいリンク元かチェックする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/310210/f0fa6fb4-b9bb-bf02-98ef-98b800d0da9d.png)
リファラを参照することで、
どこからそのページに要求が来たのかを知ることができます。
ブラウザから送信されてくるリンク元の情報である Referer を確認することで、
正しい画面遷移を行なってきていることを判断することでも CSRF の対策になります。
しかし、Referer の情報は、ユーザーの設定やセキュリティソフトなどにより情報が送信されないこともあるので、社内環境など環境と特定できる場合に利用することがよいかと思います。

***2、検証コード***
重要な情報が入力する場合、検証コードとかpasswordの入力を求めます。

***3、Tokens***
重要な処理を行うページに、hidden 項目(見えない項目)でトークンという秘密情報をセットして表示します。このとき、セッション情報としてトークンを保存しておきます。

そして、ユーザーが画面に必要情報を入力後送信処理を行うと、トークンも一緒に Webアプリケーションに送信されます。この送信されたトークンとセッションに保存しておいたトークンが等しければ、正しいリクエストだと判断できます。トークンが空だったり、値が異なればエラーとして処理をします。

## Flask-WTFのテストのCSRFトークンの扱い
- 1.バックエンドでcsrf_tokenを生成して、フロントでログインとか登録のルクエスト送る時に、csrf_tokenをフロントに送ります。
      + ファムに隠して送る
      + cookieの方法で送る
- 2.フロントで、またリクエストを送る時、csrf_tokenをバックエンドに渡します。
- 3.バックエンドで、フロントで持ってきたcsrf-tokenを検証します。
- 4.csrf-tokenの値が同じあれば、正しいリクエスト、トークンが空だったり、値が異なればエラーとして処理をします。

***全部のviewを保護するため、CsrfProtectモジュールを導入します***

from flask_wtf.csrf import CsrfProtect

CsrfProtect(app)

***テンプレートのファームにcsrf_tokenを入れます***

{{ form.csrf_token }} ``` ***テンプレートの中にファームがなくても、テンプレート内にhiddenでインプットに入れとかないと動かないです***
<form method="post" action="/">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

csrf検証失敗のリクエストを処理します

@csrf.error_handler
def csrf_error(reason):
    return render_template('csrf_error.html', reason=reason), 400

csrf検証が要らない場合

@csrf.exempt
@app.route('/foo', methods=('GET', 'POST'))
def my_handler():
    # ...
    return 'ok'

AJAX

テンプレートの< meta >にcsrf_tokenを渡します

<meta name="csrf-token" content="{{ csrf_token() }}">

テンプレートの< script >でも使えます

<script type="text/javascript">
    var csrftoken = "{{ csrf_token() }}"
</script>

AJAX(ここでは< meta >の方法を使いました)

var csrftoken = $('meta[name=csrf-token]').attr('content')

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken)
        }
    }
})

参考サイト:http://docs.jinkan.org/docs/flask-wtf/csrf.html

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?