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, (^^ゞ