web-dev-qa-db-ja.com

JSONのサニタイズは必要ですか?

私は、あらゆる入力を信用しないことが、ウェブ上でよく知られているベストプラクティスだと思います。文

「すべての入力は悪です。」

入力の検証に関しておそらく最も引用されている引用です。これで、HTMLの場合は DOMPurify などのツールを使用してサニタイズできます。

私の質問は、Expressを実行しているNode.jsサーバーと、JSONを受信して​​解析するための body-parser ミドルウェアがある場合、サニタイジングも実行する必要がありますか?

これについての私(おそらくナイーブ?)の考えは、JSONはデータのみでコードではないということです。誰かが無効なJSONを送信した場合、ボディパーサー(内部でJSON.parse()を使用します)はとにかく失敗します。有効なJavaScriptオブジェクトを受け取ります。その上でevalを実行しないか、関数を呼び出さない限り、私は大丈夫ですよね?

何か不足していますか?

21
Golo Roden

JSON.parse()は解析するデータのコードを実行しないため、eval()のように脆弱ではありませんが、サーバーの整合性を保護するためにすべきことはまだあります次のようなアプリケーション:

  1. JSON.parse()が例外をスローする可能性があるため、適切な場所に例外ハンドラを適用します。
  2. そこにどのようなデータがあるかを想定しないでください。データを使用する前に、明示的にテストする必要があります。
  3. 特に探しているプロパティのみを処理します(JSONにある可能性のある他のものは避けます)。
  4. すべての受信データを正当で許容可能な値として検証します。
  5. データの長さをサニタイズします(過度に大きなデータによるDOSの問題を防ぐため)。
  6. この受信データを、ページのHTMLに直接評価したり、その環境に安全であることを確認するためにさらにサニタイズすることなくSQLステートメントに直接挿入したりするような場所に配置しないでください。

したがって、質問に直接答えるには、「はい」です。ボディパーサーを使用するだけでなく、最初にデータを処理するための完全な前線です。 body-parserから取得したデータをどのように処理するかの次のステップは、多くの場合重要であり、特に注意が必要です。


例として、これらのチェックの一部を適用するプロパティを持つオブジェクトを期待し、期待していたプロパティのみを含むフィルターされた結果を提供する解析関数を次に示します。

// pass expected list of properties and optional maxLen
// returns obj or null
function safeJSONParse(str, propArray, maxLen) {
    var parsedObj, safeObj = {};
    try {
        if (maxLen && str.length > maxLen) {
            return null;
        } else {
            parsedObj = JSON.parse(str);
            if (typeof parsedObj !== "object" || Array.isArray(parsedObj)) {
                safeObj = parseObj;
            } else {
                // copy only expected properties to the safeObj
                propArray.forEach(function(prop) {
                    if (parsedObj.hasOwnProperty(prop)) {
                        safeObj[prop] = parseObj[prop];
                    }
                });
            }
            return safeObj;
        }
    } catch(e) {
        return null;
    }
}
19
jfriend00

あなたは大丈夫です。 JSONの初期のユーザーは、受信した文字列でeval()を呼び出すことがよくありますが、これはもちろん巨大なセキュリティホールです。しかし、JSON.parseは、あなたが述べているように、これらの種類の健全性チェックの大部分を処理します。

たとえば、受け取ったJSONオブジェクトから何かを取り出さないようにし、それをSQLクエリに直接渡さない限り、問題はありません。

5
Chris Tavares