JavaScript のブラケット表記 とは
オブジェクトのプロパティに obj["prop"]
のようにアクセスする方法のことです。
const user = {
name: "John",
age: 30,
isAdmin: false
};
console.log(user.name); // ドット表記
console.log(user["name"]); //ブラケット表記
静的解析での警告
Gitlab の静的解析機能で静的解析を行ったところ、次のような警告が出ました。
{
"message": "Improper Control of Generation of Code ('Code Injection')",
"description": "Bracket object notation with user input is present, this might allow an attacker to access all properties of the object and even it's prototype, leading to possible code execution.",
"severity": "Medium",
"location": {
"file": "apps/frontend/src/xxxx.ts",
"start_line": 14
}
}
この警告は簡単に言うと ブラケット表記を使うと、悪意のあるユーザから任意のプロパティにアクセスされてしまう可能性があるよ! というものです。
具体例
ユーザが自分の情報について任意の項目名と値で登録できる機能がある場合、下記のような実装だと他のプロパティを書き換えられてしまいます。(そんな実装するかいな!と思うかも知れませんが。)
const user = {
name: "John",
age: 30,
isAdmin: false
};
// ユーザから入力を受け取る
const customField = prompt("Input custom field name.")
const customValue = prompt("Input custom value.")
user[customField] = customValue;
この例だと、ユーザが項目名を name
にすると、既存の user.name
の値を上書きされてしまいます。
対策
十分にバリデーションを行う
すでに存在するキーは禁止するなど、十分にバリデーションを行うことで回避します。
if (user.hasOwnProperty(customField)) {
alert('その項目名は利用できません')
} else {
user[customField] = customValue;
}
キー名をユーザに指定させない
const user = {
name: "John",
age: 30,
isAdmin: false,
// キー名はこちらで指定したものにしておく
customField: {
name: "",
value: "",
}
};
// ユーザから入力を受け取る
const customField = prompt("Input custom field name.")
const customValue = prompt("Input custom value.")
// ドット表記でアクセスして代入する
user.customField.name = customField;
user.customField.value = customValue;
まとめ
静的解析を実行したときに警告が出たので、どのような場合に危険なのか、気になったので調べてみました。
結論としては、ユーザから受け取った任意の値でプロパティにアクセスしていなければ問題なさそうです。