Hello there, ('ω')ノ
🧩 NoSQLインジェクションの2つのタイプ
NoSQLインジェクションには大きく分けて以下の2種類が存在します:
① 構文インジェクション(Syntax Injection)
概要:
- NoSQLのクエリ構文そのものを壊して、意図的に攻撃用の構文を注入する。
- SQLインジェクションに近い発想だが、NoSQLではJSON形式などが用いられるため攻撃方法が異なる。
例(MongoDB):
{"username": "admin", "password": {"$ne": null}}
この入力により、パスワードが空でなければ認証を通すという条件に改ざんできる。
特徴:
- 多くのNoSQLがJSON形式の構文を採用しており、クエリにJSONオブジェクトを直接挿入できるケースが多い。
- 構文が破壊されてもエラーが出ず、静かに意図しない動作をする場合がある。
② 演算子インジェクション(Operator Injection)
概要:
$ne
,$or
,$gt
などのMongoDB固有の演算子をパラメータに挿入して、条件の意味そのものを変える攻撃。
例(MongoDB):
{"username": {"$ne": ""}, "password": {"$ne": ""}}
- どんなユーザーでも、空でさえなければ認証が通ってしまう。
$or
,$and
を使えばさらに複雑な条件も作成可能。
🧪 テスト方法と注意点
テスト方法 | 解説 |
---|---|
ログイン画面で JSON を試す | パラメータを {"$ne": null} などに変更してみる |
パスワードなしで通るか試す | password={"$gt":""} などの条件で通過するか確認 |
異常な構文でエラーを確認 | クエリエラーが返るかチェック(エラーメッセージにヒントあり) |
入力値に $ や {} が使えるか |
クエリ構築時にそのまま使われるかどうか確認する |
🧠 攻撃ポイント(MongoDB)
狙いどころ | 例 |
---|---|
$ne , $gt , $lt を使った比較のすり抜け |
password: {"$ne": null} |
$or を使った条件の分岐 |
{"$or": [{"username":"admin"}, {"username": {"$ne": null}}]} |
$where によるJavaScriptの挿入 |
"$where": "this.password.length < 100" |
$regex を使ったパターンマッチ |
username: {"$regex": ".*"} (全一致) |
🛡 対策
対策 | 内容 |
---|---|
JSON構造のバリデーション | パラメータが文字列であることを厳密にチェック |
$ や {} のフィルタリング |
クライアント入力に含まれていないか検査・除去 |
OR条件などを組めないように設計 | クエリ構築ロジックを一元管理し、テンプレート化する |
ORMや公式ドライバの利用 | 手動で文字列結合せず、正規の手段でクエリを構築する |
✅ まとめ
- NoSQLインジェクションは構文ベースの操作か、演算子の悪用のどちらかで分類できる。
- 特にMongoDBでは、JSON構文の柔軟性を逆手に取った高度な改ざんが可能。
- 安易な入力値の埋め込みは厳禁。型チェックと構造検証が防御の要。
🔐 柔軟なデータ構造は、攻撃者にとっても柔軟な武器になる。開発者側の制限がなければ、セキュリティは成立しない。
Best regards, (^^ゞ