NoSQLインジェクションとは?仕組みと対策をわかりやすく解説
公開日:
※当サイトはアフィリエイトプログラムを利用しています。
「SQLインジェクションは対策しているから大丈夫」と思っていませんか?
柔軟なデータ構造と高い処理スピードからMongoDBなどのNoSQLデータベースを採用するWebアプリケーションやモバイルアプリが増えています。
しかし、「SQLを使わないからSQLインジェクションは起きない」と油断していると狙われるのがNoSQLインジェクションです。
パスワードを入力せずに管理者としてログインされたり、データベース内の個人情報が無制限に盗み出されたりするなど、深刻な被害につながる攻撃手法です。
今回は、NoSQLインジェクションの仕組みや具体的な悪用例、そしてWebサイト運用者やエンジニアが講じるべき根本対策まで分かりやすく解説していきます。
NoSQLインジェクションってどんな攻撃?
NoSQLインジェクションとは、ユーザーからの入力値(フォームやAPIリクエストのJSONデータなど)の検証が不十分な場合、攻撃者がデータベース操作命令(演算子やJavaScript式など)を混入させ、開発者の意図しないクエリを実行させる攻撃です。
従来のRDB(リレーショナルデータベース)に対するSQLインジェクションはSQL文の構造を破壊する手口ですが、MongoDBなどのNoSQLではJSONオブジェクトの構造や特殊演算子($ne, $gt, $whereなど)を悪用する点が大きく異なります。
SQLインジェクションとは?サイトが乗っ取られる仕組みと今すぐできる3つの対策
ここで、基本的な用語と仕組みを整理しておきましょう。
- NoSQLデータベースとは
- MongoDB、CouchDB、DynamoDBなど、従来の表形式(SQL)ではなくJSON形式(ドキュメント型)などでデータを管理するデータベース。柔軟性と高速処理が特徴。
- 演算子インジェクション(JSON / BSON)
- Webアプリが文字列として受けるはずの入力欄に、JSON形式で
{"$ne": ""}(〜と等しくない)などの条件演算子を送り込み、条件判定を歪める手口。 - JavaScriptインジェクション($where等)
- MongoDBなどの機能で、クエリ内にサーバー側JavaScriptを実行できる仕組み(
$where)があり、そこに悪意あるスクリプトコードを注入する手口。
例えば、通常のログイン処理でバックエンドが以下のようにリクエストボディ(JSON)をそのままクエリに渡しているケースを考えます。
// 開発者が想定しているリクエストデータ(文字列)
{ "username": "admin", "password": "mypassword123" }
// データベース検索クエリ
db.users.find({ username: req.body.username, password: req.body.password })
攻撃者がリクエスト内のpassword欄に、文字列ではなくオブジェクト形式の演算子を注入するとどうなるでしょうか。
// 攻撃者が送信する悪意のあるJSONデータ
{ "username": "admin", "password": { "$ne": "" } }
// 実行されてしまうデータベース検索クエリ
db.users.find({ username: "admin", password: { "$ne": "" } })
$neは「Not Equal(等しくない)」を意味するため、このクエリは「ユーザー名がadminで、パスワードが空文字以外であるデータ」を検索することになります。
結果として、パスワードが合致していなくてもクエリが真(True)となり、管理者としてログインが成功してしまうのです。
被害に遭うとどうなる?
NoSQLインジェクションの脆弱性が放置されていると、認可のバイパスからサーバーの全乗っ取りまで、多岐にわたる深刻な被害が発生します。
認証突破(パスワードなしでのログイン)
前述の通り、条件演算子($neや$gtなど)を注入されることで、パスワードを知らなくても他人のアカウント、特に管理者権限へ不正ログインされてしまいます。
- 全ユーザーアカウントの流出
管理権限を乗っ取られることで、会員データベース全体へのアクセスを許してしまう - 不正操作・権限昇格
一般ユーザーが他人のマイページを閲覧したり、決済情報や設定を勝手に書き換えたりすることが可能になる
データベース内の個人情報・機密情報の漏えい
ブラインドNoSQLインジェクションと呼ばれる手口を使うことで、攻撃者は一文字ずつエラー応答や応答時間の変化を観察し、データベース内に格納されている全データ(氏名、住所、クレジットカード情報、暗号化ハッシュなど)を抽出できます。
データの改ざん・不正削除
クエリの文脈によっては、検索処理だけでなく更新(update)や削除(remove/delete)処理にインジェクションが及ぶケースもあります。
これにより、顧客データの一括削除や所有者情報の改ざんなど、事業の継続を脅かす被害が発生します。
サーバー側でのJavaScript実行によるDoS・遠隔操作
MongoDBの$where節やmapReduce機能にユーザー入力が組み込まれている場合、サーバー上で任意コード(JavaScript)を実行される危険(RCE)があります。
無限ループを仕込まれてサーバーをダウンさせられたり(DoS攻撃)、サーバー内部のファイル読み書きや外部への攻撃台として悪用されたりすることがあります。
個人事業主やサイト運営者向けの緊急対応
自身が運用するWebアプリやAPIで「不審なログイン履歴がある」「大量のデータ取得アクセスが発生している」などの異常を検知した際に、直ちに実行すべき応急処置です。
- 被害の拡大を止める
- ・該当するログイン機能やAPIエンドポイントの停止
脆弱性が疑われるAPIやフォームへのアクセスを一時的に制限・遮断する。 - ・WAF(Webアプリケーションファイアウォール)の緊急ルールの適用
JSONリクエスト内に$neや$regexなどの特殊ドメインキーが含まれるリクエストをブロックするルールを有効化する。
- 証拠保全と影響範囲の把握
- ・Webサーバーおよびデータベースのログ保管
リクエストボディのログやDBアクセスログを保存し、どのデータが参照や改ざんされたかを特定する。 - ・影響を受けたアカウントのセッション無効化
不正ログインされた可能性のあるユーザーのセッションを即座に破棄し、再ログインを求める。
- 安全な状態への復旧と根本対策
- ・入力値の型検証(バリデーション)の導入
受け取る値が必ず「文字列(string)」であることを確認・強制するキャスト処理を入れる。 - ・ORM/ODM(Mongoose等)のスキーマ定義を厳格化
受け取ったJSONを直接クエリに渡さず、型定義に適合したものだけを処理するように修正する。
- 外部への報告と利用者対応
- ・ユーザーへのパスワードリセットや案内
個人情報の流出が懸念される場合は、被害対象の特定とユーザーへの速やかな報告や注意喚起する。 - ・専門機関や警察サイバー犯罪相談窓口への相談
大規模な個人情報漏えいや不正アクセスの場合は、IPAや警察、個人情報保護委員会等へ届け出る。
※NoSQLインジェクションは、Node.js + Express + MongoDBなどのWeb APIでJSONリクエストを直接パースして受け渡す際に極めて発生しやすいため、API設計の確認が急務です。
利用しているサービスが被害に遭った場合の対処法
利用しているWebサービスがNoSQLインジェクション攻撃を受け、情報漏えいや不正ログインの発表があった場合に利用者が取るべき行動です。
- アカウントの保護
- ・同一パスワードを使い回している他サイトのパスワードを変更する
認証突破やハッシュ化されたパスワードが漏えいした場合、リスト型攻撃に悪用される危険があります。 - ・2段階認証を設定する
万が一パスワードが流出しても、2段階認証を設定しておくことで不正ログインを防げます。
- 不審な問い合わせやフィッシングへの警戒
- ・お詫びメールを装った偽連絡に注意する
「漏えいのお詫び」を騙ってクレジットカード番号や暗号資産の入力を促すフィッシングメールが増加します。公式サイトのお知らせを直接確認しましょう。
あわせて読みたい
フィッシング被害に遇ったら?フィッシングを防ぐ確実な方法とは
システム開発(設計)側の根本対策
NoSQLデータベースを使用するWebサイトやアプリケーション開発において、NoSQLインジェクションを防ぐための必須対策をまとめました。
- 目次
- ・入力値の型(Type)チェックとキャストの徹底
- ・スキーマベースのODM / ORMを利用する
- ・JavaScript実行機能の無効化($whereの禁止)
- ・データベース権限の最小化と監査ログの設定
1️⃣入力値の型(Type)チェックとキャストの徹底
もっとも根本的かつ効果的な対策は、ユーザーからの入力値が意図した型(文字列や数値など)であるかを厳格に検証することです。
JSONボディから送られてくる値は、文字列だけでなくオブジェクトや配列の可能性もあります。String(req.body.password)のように明示的に文字列型にキャスト(変換)するか、express-validatorやJoi、Zodなどのバリデーションライブラリを用いてオブジェクトが混入しないよう検証します。
2️⃣スキーマベースのODM / ORMを利用する
MongoDBであれば Mongoose などのODM(Object Data Modeling)ライブラリを使用し、スキーマ(データ構造の定義)を厳密に定義して運用しましょう。
適切なスキーマ定義がなされていれば、文字列として指定されたフィールドに {"$ne": ...} のようなオブジェクトが渡されても、自動的に無視されたり型エラーとして弾かれたりするため、インジェクションの発生を防げます。
3️⃣JavaScript実行機能の無効化
クエリ内でJavaScriptを実行できる $where や mapReduce の使用を避け、クエリ構築には宣言的なMongoDB演算子のみを使用してください。
また、データベースの設定ファイル(mongod.conf)で security.javascriptEnabled: false を設定し、DBレベルでJavaScriptの実行を完全に無効化することが強く推奨されます。
4️⃣データベース権限の最小化と監査ログの設定
アプリケーションがデータベースに接続する際のアカウントには、必要な最小限の操作権限、例えば特定コレクションの読み書きのみだけを与えます。万が一インジェクションが発生しても、被害範囲を局所化できます。
あなたが運営するサイトを守るための基本対策
開発者だけでなく、Webサイト運用者やセキュリティ管理者も日頃からの運用管理が欠かせません。
- ・Node.jsやMongoDBの関連ライブラリを常に最新版に更新する
- ・WAF(Web Application Firewall)を導入し、不正なJSONパターンを遮断する
- ・Web APIの仕様書(OpenAPI / Swaggerなど)で型定義を厳格に指定する
- ・定期的な脆弱性診断(ペネトレーションテスト)を実施し、隠れたインジェクションを検出する
「SQLを使っていないからインジェクションとは無縁」という思い込みこそが最大のリスクです。
正しい知識と型検証の徹底により、安全なWebサービスを構築していきましょう。
NoSQLインジェクションのよくある質問
NoSQLインジェクションに関して、よくある疑問をQ&A形式でまとめました。
- 目次
- ・SQLを使っていなければインジェクション攻撃は受けませんか?
- ・バイブコーディングで開発したアプリは安全ですか?
- ・Mongooseを使っていれば100%安全ですか?
- ・WAFだけで完全に対策できますか?
Q. SQLを使っていなければインジェクション攻撃は受けませんか?
A.いいえ、SQLを使っていなくてもインジェクション攻撃は発生します。
インジェクションとは「プログラムの命令文に不正なデータを混ぜ込んで構造を破壊・改ざんする手口」全般を指します。
NoSQLであっても、JSONの構文や条件演算子、JavaScriptコードを混入されることで同様の被害が発生します。
Q. バイブコーディングで開発したアプリは安全ですか?
A.むしろ注意が必要です。
ChatGPTやClaude、CursorなどのAIツールに「ExpressとMongoDBでログイン処理を作って」と頼むと、db.collection.findOne(req.body) のように、リクエストボディをそのままクエリに渡すコードを生成してしまうケースが多々あります。
「入力値を型チェックして」「Mongooseのスキーマを通してバリデーションをして」という具体的な指示を与えない限り、AIが脆弱性のあるコードを出力してしまう可能性があるため、人間によるレビューが必須です。
あわせて読みたい
バイブコーディングとは?AI時代のアプリ開発に潜むリスクと正しい向き合い方
Q. Mongooseを使っていれば100%安全ですか?
A.使い方によっては脆弱性が残ります。
Mongooseは型安全を提供しますが、Schema.Types.Mixed を使用して任意のオブジェクトを受け入れ可能にしていたり、$where 内で未検証のユーザー入力を連結していたりすると、インジェクションが可能になります。
適切な型定義と機能制限を組み合わせることが重要です。
Q. WAFだけで完全に対策できますか?
A.WAFのみに頼るのは危険です。
WAFは既知の攻撃パターン($ne や $gt などの文字)を検知して遮断しますが、難読化されたリクエストや特殊なAPI仕様を完全にカバーすることはできません。
コードレベルでの入力値検証(バリデーション)という根本対策と組み合わせて運用することが原則です。
