"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

WebApi実行時のレスポンスヘダーをChromeの開発者ツールでチェックする

WebApiで重要な役割を持つ「レスポンスヘダー」の確認を、Chromeデベロッパーツールを用いて確認する手順を整理してみます。

f:id:arakan_no_boku:20190607195913j:plain

 

レスポンスヘダーで確認したいこと

 

DjangoのRESTフレームワークを使うということは、自動的にレスポンスヘダーの出力はフレームワークにおまかせすることになります。

まあ、実績のあるフレームワークなので、信用しておまかせで全然いいんです。

だけど、フレームワークがどんなレスポンスヘダーを出力しているかを知らずに、ブラックボックスのままなのは、気持ちが悪い。

だから確認しておこうと思ってます。

勉強にもなりますし。

特に、確認してみたいポイントの項目としては。

  • CORS対策のヘダーがセットされているか確認
  • Content/typeの設定を確認
  • CSRFトークンの確認
  • その他セキュリティ強化につながるヘダーの確認

という感じです。

ポイントを個別に補足します。

 

CORS対策のヘダーがセットされているか確認

 

CORS対策は、Djangoの機能を使ってやっています。

概要の説明は以下の記事に書いています。

arakan-pgm-ai.hatenablog.com

設定がきちんとできていれば、「Access-Control-Allow-Origin」がレスポンスヘダーに出力されているはずです。

設定にミスっていれば、出力されません。

だから、それを確認します。

 

Content/typeは適切に設定されているか確認

 

WebApiではJSONを返す仕様にしています。

当然、MIMEタイプは「application/json」です。

フレームワークを正しく使えていれば、ちゃんと出力されるので、そこを確認です。

自分はあまりであった事がないですが、セキュリティ関係の書籍とか読んでいると、よく「MIMEタイプが間違ってtext/htmlなどに間違っているAPIは良く見かけます」なんて書いてあります。

JSONの直接表示によるXSS攻撃は、この間違いが根本原因だったりしますしね。

ja.wikipedia.org

だからまあ、大事なポイントでもあるので。

 

CSRFトークンの確認

 

CSRF攻撃は、一応WebApiでもありえます。

ja.wikipedia.org

対策としては

  • GETで更新処理のような重要な処理をうけつけない。
  • MIMEタイプを正しく設定する。
  • CORS対策が適切に行われている。

とかを、きちんと守っているということが、まず重要なわけです。

本来なら、その土台の上に、「CSRFトークン」をAPIで返してチェックするとかの対策を加えていくわけですが、今回は、特に何もしてません。

でも、チェック項目としてはあげておこうって感じです。

 

その他セキュリティ強化につながるヘダーの確認

 

自分はセキュリティの専門家ではないので、結構「ウロ」なんですが、レスポンスヘッダーに常に出力しておくと、セキュリティ強化に役立つ仕組があるということは、よく聞きます。

代表的なものが

  • X-Frame-Options
  • X-Content-Type-Options
  • X-XSS-Protection
  • Content-Security-Policy

などです。

とりあえず、そのあたりがRESTフレームワークの出力でどの程度カバーされているのかとか、一応把握しておきたいなと思っています。

 

Chromeでの確認方法

 

まず。

動作確認のため、NuxtとDjangoの各サーバーを動かしておきます。

環境とか実行方法は前回の記事のままなので、こちらを参照ください。

arakan-pgm-ai.hatenablog.com

これでサーバーを起動して、郵便番号検索のページをChromeで開いている状態から説明を開始します。

f:id:arakan_no_boku:20190619001842p:plain

画面上で右クリックして、メニューで「検証」を選択します。

f:id:arakan_no_boku:20190619002108p:plain

デベロッパーツールが表示されたら「network」を選びます。

f:id:arakan_no_boku:20190619002247p:plain

初期状態はこんな感じです。

ここで、画面で郵便番号を入力して、住所情報取得ボタンを押します。

すると。

f:id:arakan_no_boku:20190619002554p:plain

みたいに、WebApiのレスポンスが表示されます。

ここでNameのところをクリックすると。

f:id:arakan_no_boku:20190619002835p:plain

 

上記の例だと、こんな感じで、ヘダー情報やレスポンスの内容などが出力されてます。

Access-Control-Allow-Origin: http://localhost:3000
Allow: GET, HEAD, OPTIONS
Content-Length: 238
Content-Type: application/json
Date: Tue, 18 Jun 2019 15:25:28 GMT
Server: WSGIServer/0.2 CPython/3.7.3
Vary: Accept, Origin, Cookie
X-Frame-Options: SAMEORIGIN

単にResponseを返すだけの超シンプルなことしかやってないわけですが。

 Access-Control-Allow-Originはきちんと出力されていて。

Content-Type: application/jsonもOKです。

シンプルですが、押さえるところは、きちんとされているって感じですか。

 

直接WebApiをたたいた時のレスポンスヘダーも参考までに

 

市区町村APIをaxiosを使ってたたいてみます。

こちらの記事で作ったものです。

arakan-pgm-ai.hatenablog.com

こちらのAPIは、郵便番号APIと違って、WebApiプロキシを挟まなくても、データを取得できるのですね。

そちらが返してくるレスポンスヘダーはこんな感じでした。

access-control-allow-credentials: false
access-control-allow-headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent
access-control-allow-methods: OPTIONS,GET
access-control-allow-origin: *
content-length: 0
content-type: application/json
date: Thu, 20 Jun 2019 13:31:46 GMT
status: 200
via: 1.1 6fc9bea777dbb883661b140062657912.cloudfront.net (CloudFront)
x-amz-apigw-id: blKeVHhYNjMFl5A=
x-amz-cf-id: YEDPGfAGsD1-sLPbJa2w5gsUVLzYicM2FCeIlWIZv82KWpL5X9aoFQ==
x-amz-cf-pop: NRT20-C3
x-amzn-requestid: bfde3e49-935f-11e9-aedb-7b650bee618d
x-cache: Miss from cloudfront

こちらは「access-control-allow-origin: *」になってますね。

汎用WebApiですから、ホワイトリストは使えないから当然かなと思います。

まあ、それだけではなく、access-control-allow-***が色々設定されてますけど、そこをつっこみはじめると、セキュリティの話にがっつりなってしまうので、この辺にしておきます。

ということで。

レスポンスヘダーの確認方法という、知ってれば簡単だけど、知らないと迷う類の話を簡単にまとめてみました。

ではでは。