DynamoDBへのNoSQLインジェクション攻撃
RDB(SQL)よりは危険性は少ないですが、DynamoDB(NoSQL)でも攻撃される可能性はあります。
私の場合はDynamoDBへのアクセスにDynamooseを使っているので、Dynamooseを使った例を説明します。とはいえ、AWS SDKを直接呼び出す場合も、基本的な考え方は同じです。
コード例
'use strict';
// awaitを使いたいので、async関数を即時実行しています(雑ですが・・)。
(async () => {
// AWS SDKに~/.aws/configのリージョンを読み込ませる
process.env.AWS_SDK_LOAD_CONFIG=true;
const AWS = require('aws-sdk');
const dynamoose = require('dynamoose');
dynamoose.setDDB(new AWS.DynamoDB());
dynamoose.setDefaults({ create: false, waitForActive: false });
// AWS環境上に、以下の定義で「dynamo-user」という名前のテーブルが作られている前提です。
const tableSchemaDef = {
"user_id": {
"type": "String",
"hashKey": true
},
"first_name": {
"type": "String"
}
}
const tableSchema = new dynamoose.Schema(tableSchemaDef);
const TableModel = dynamoose.model('dynamo-user', tableSchema);
// Case 1
// こんな値が外部から入力されてきたとします。
const bad_input1 = '*';
// 大抵の文字はASCIIの並び順的に、*よりも大きいので実質的に全件取得できてしまいます。
const result1 = await TableModel.scan('first_name').gt(bad_input1).exec();
result1.forEach(item => console.log(item));
console.log("Case 1 end.");
// Case 2
// 外部から入力されたものをJSON.parse()した結果に、こんなJSONが含まれていたとします。
const bad_input2 ={"first_name": {"gt": "*"}};
// 大抵の文字はASCIIの並び順的に、*よりも大きいので実質的に全件取得できてしまいます。
const result2 = await TableModel.scan(bad_input2).exec();
result2.forEach(item => console.log(item));
console.log("Case 2 end.");
})()
参考
https://medium.com/appsecengineer/dynamodb-injection-1db99c2454ac
https://blog.sqreen.com/mongodb-will-not-prevent-nosql-injections-in-your-node-js-app/