TakayukiTomatsuri / sellerInfoValidator

0 stars 0 forks source link

メアドのレピュテーションを得る際、WebAPI的なのからJSONだけじゃなくてWebページ全体が応答される。JSONで欲しい #1

Closed TakayukiTomatsuri closed 4 years ago

TakayukiTomatsuri commented 4 years ago

使用しているサービスはこれ。 https://emailrep.io

サイトに書いてあるように curl https://emailrep.io/<調べたいメアド> とかでJSONが返ってくるんだけど、 User-Agentを見て応答を変えてるのか、普通のブラウザやJSのXMLHttpRequest を使うとWebページ全体が応答される。

処理がメンドイので、User-Agentをcurlのものに変えてただのJSONで返してもらう必要がありそう...

TakayukiTomatsuri commented 4 years ago

結論からいってUser-Agent変えただけじゃ、JSONで応答してくれないっぽい?

curlのやり方によって応答が違う。でも理由がわからない。

User-Agentを変えて通信してみた

curlコマンドでやるとUser-Agentは curl/7.54.0 になる。

以下のようにユーザエージェントを(わざわざ)指定してcurlをやってみたら、なぜか失敗した。APIキーが必要ってことかな? 単純に curl コマンド使ったときと何が違うんだろ…?

$ curl  -H "User-Agent: curl/7.54.0" https://emailrep.io/bill@microsoft.com

{"status": "fail", "reason": "unauthorized"}

なお公式ページ に書いてあるとおりヘッダとか指定せずcurlを使うと、普通に通信できるしJSONを返してくれる。

$ curl https://emailrep.io/bill@microsoft.com

{
  "email": "bill@microsoft.com",
  "reputation": "high",
  "suspicious": false,
  "references": 90,
  "details": {
    "blacklisted": false,
    "malicious_activity": false,
    "malicious_activity_recent": false,
    "credentials_leaked": true,
    "credentials_leaked_recent": false,
    "data_breach": true,
    "first_seen": "07/01/2008",
    "last_seen": "06/29/2020",
    "domain_exists": true,
    "domain_reputation": "high",
    "new_domain": false,
    "days_since_domain_creation": 10730,
    "suspicious_tld": false,
    "spam": false,
    "free_provider": false,
    "disposable": false,
    "deliverable": true,
    "accept_all": true,
    "valid_mx": true,
    "primary_mx": "microsoft-com.mail.protection.outlook.com",
    "spoofable": false,
    "spf_strict": true,
    "dmarc_enforced": true,
    "profiles": [
      "angellist",
      "vimeo",
      "linkedin",
      "flickr",
      "twitter",
      "myspace"
    ]
  }
}

diffをとって何が違うか見てみる

結論からいって何が違うせいで失敗するのかわからなかった。

curlは -v オプションでHTTPリクエストの詳細を見せてくれる。( -s は進捗を表示しないオプション)

# 普通にcurl使った場合
curl -v -s https://emailrep.io/bill@microsoft.com $> normal.log
# curlで User-Agentを(わざわざ)変更してみた場合
curl -H "User-Agent: curl/7.54.0" -v -s https://emailrep.io/bill@microsoft.com  $> change-user-agent.log

これらのdiffをとる。 HTTPヘッダの並び順が違うだけに見える。

$ diff -y normal.log  change-user-agent.log

> GET /bill@microsoft.com HTTP/1.1                |   > GET /bill@microsoft.com HTTP/1.1
> Host: emailrep.io                       |   > Host: emailrep.io
> User-Agent: curl/7.65.3                     |   > Accept: */*
> Accept: */*                             |   > User-Agent: curl/7.54.0

HTTPヘッダの並び順を同じにしてみたが、ダメ。ヘッダを指定したときと指定してない時、一体何が違うんだ?

$ curl -H "User-Agent: curl/7.54.0" -H "Accept: */*" -v -s https://emailrep.io/bill@microsoft.com

{"status": "fail", "reason": "unauthorized"}

Wiresharkで比較してみる

何回もemailrep.ioにリクエストすると1日の使用制限に達してしまうので、代わりにgoogle.comを使う

単純なcurlと、ヘッダをわざわざ変えたcurlでのリクエストを比べる

# 普通にcurl
curl  http://google.com

# ヘッダをわざわざ書き換えてcurl
curl  -H "User-Agent: curl/7.54.0" -H "Accept: */*" -v  http://google.com

Wiresharkの、該当のパケットの情報をテキストでコピーしてdiffをとると以下の画像のとおり。HTTPリクエストのパケットに違いはないように見える。 だが(この画像には出てないが)単純なcurlのほうは判定結果をJSONで返してくるが、ヘッダをわざわざ書き換えてcurlしたほうは {"status": "fail", "reason": "unauthorized"} という失敗を表すJSONが返ってくる。 image

単純なcurlと、ブラウザからのリクエストを比べる

左がcurl、右がブラウザ。 image

当然ヘッダが違う。

でもemailrep.ioはHTTPヘッダだけみて応答を変えてるわけじゃないはず…。 なぜなら↑で比べた単純なcurlとヘッダをオプションでわざわざ変えたcurlでは、リクエストの内容はみた感じ変わらんのに応答が違うから。それの説明がつかない。

結論

よくわからん どうやったら、単純にcurlでリクエストしたときみたいにJSONを返してもらえるんだ??

kazuya-n commented 4 years ago

https://github.com/sublime-security/emailrep.io-python/blob/9947fd3b094009c0ef8635f23af09242fbbc000b/emailrep/__init__.py#L11 まだ試せてないけどこれ参考にならない?公式のpythonライブラリなんだけど、色々ヘッダに書いてるっぽい

kazuya-n commented 4 years ago

https://github.com/sublime-security/emailrep.io/issues/3 こんなの見つけた (ごめんバイト中なので試せてない。。。) (仕事しろ)

TakayukiTomatsuri commented 4 years ago

sublime-security/emailrep.io#3 こんなの見つけた (ごめんバイト中なので試せてない。。。) (仕事しろ)

役に立ちそうな情報!ありがとう。

You can now also force a JSON response using the "Accept: application/json" HTTP header.

これで行けるかも。試してないけど

TakayukiTomatsuri commented 4 years ago

できましたー。 ただし、表示は適当。判定結果のJSONがドンとそのまま表示されるだけ。 image