Ruby と Node.js 間の HAMC を使った正当性検証でPOST のボディーがJSON 文字列の場合にはまったこと

1 min read読了の目安(約900字

概要

javascript (express)application/json の POST リクエストを受けると、
Object にパースされる際に、小数点以下が 0 の浮動小数点が、整数に自動変換される。

これは、express というよりは、javascript の仕様のように見受けられる。
(ドキュメントを確認したわけではなく、実行結果からの判断です。)

1.01

以下のようなJSONだった場合

{
  duration: 3.0
}

express で受け取ってパースすると、

{
  duration: 3
}

となる。

リクエスト発信元は 3.0JSON文字列 を生成して、
それをペイロードとして HMAC のハッシュ値を生成しているので、
受け取り側で上記のようになるとハッシュ値が合わなくなる。

結論

いくつかの対策方法が考えられます。

  1. そもそも数値のフィールドをなくし、全て文字列フィールドにする
  2. 整数の場合は、小数点以下をなくす
  3. 受け取り側で無理やり全部浮動小数点に変換する

1 は安全ですが、適切かどうかは微妙。でも初めからこの事に気づいていたらこれを採用したはず。気づいた時点では既に9割型完成していて仕様変更するべきではないと判断したので、私の場合は見送り

2 を今回は採用することにしたが、フィールドが 整数浮動小数点 なのか定まっていないのは微妙な気がする。

3 は無駄な処理が発生しすぎると思う。12 はリクエスト発信側の調整で対応するものなので、やんごとなき理由で、発信側の調整ができない場合の対応となるかと思います。

背景

外部のシステムから届く通知メールを AWS Lambda にある Ruby にて、
本文から必要な情報だけ抜き出して JSONパース

そのJSONを、 Node.js + Firebase Functions で構成される他の自前実装システムに送信して、正当性検証を行った後、リクエスト内容を元に処理する必要があった。