兵どもが、夢のあとさき

JavaScript 系の言語に興味を惹かれ、まったりと更新しております

JSONあれこれ(3)

どのようにアクセスすればよいのでしょうか?

 

と、その前に、このプログラムのセキュリティ等に関してまとめておきます。

 

 まず、下記ですがプログラム内のコメントにもありますように、「JSONハイジャック攻撃」を防止するために、受信HTTPヘッダ(x_request_with)をチェックしています。先ほど直接アクセスしても『不正な呼び出しです』と表示されたのは、それが理由です。

# jQueryなど主要なJavaScriptライブラリを通じてのアクセスである
# (ブラウザからの直接アクセスでない)ことを確認します。
# この方法はJSONハイジャック攻撃など☆レシピ305☆(JSONのセキュリティについて知りたい)に対しても有効です。
if (! isset($_SERVER['HTTP_X_REQUESTED_WITH']) ||
    $_SERVER['HTTP_X_REQUESTED_WITH'] !== 'XMLHttpRequest') {
  die(json_encode(array('status' => "不正な呼び出しです")));
}

 

ブラウザ等の受信側に、JSONデータを返すことを明確にヘッダで指定します。

# Content-Typeを「application/json」に設定します。
header("Content-Type: application/json; charset=UTF-8");

 

 受信したデータのMIMEタイプは、上記の Content-Type から決定されるべきです。しかし、IEでは受信データのコンテンツから決定する「仕様」があるようです。コンテンツの内容からMIMEタイプを判断した場合、HTMLでないデータがHTMLと判断され、XSS脆弱性が発生する可能性があります。

 IE8以降では、下記ヘッダを指定することで、この「仕様」を無効にすることが可能となります。

 IEがアクセスするサイト(!)は、上記のMIMEの設定をきちんと行い、下記のヘッダも同時に出力すれば間違いないようです。

# Internet ExplorerがContent-Typeヘッダーを無視しないようにします☆レシピ287☆(XSS対策をしたい)。
header("X-Content-Type-Options: nosniff");

 

 可能な限りのエスケープを行ない、JSON形式で結果を返します。

「<」「>」等のコードをそのままにしておくと、XSSの危険性がありますので、できうる限りエスケープします。

echo json_encode(
  $value,
  JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
);

パラメータの意味は下記の通りです。

JSON_HEX_TAG 「<」「>」を、\u003C及び\u003Eに変換
JSON_HEX_APOS 「'」を、\u0027に変換
JSON_HEX_QUOT 「"」を、\u0022に変換
JSON_HEX_AMP 「&」を、\u0026に変換