1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】XML / JSON Injection —— 構造化データでも油断すると即 SQL Injection

Posted at

はじめに

JSON や XML の入力だから安全?
いえ、残念ながら 構造化データでも中身の値は普通に注入されます

REST API、GraphQL、モバイルアプリの普及によって、アプリは JSON/XML を大量にパースします。その入力値を SQL に直接渡してしまうと、古典的な SQL Injection と同じように攻撃が成立します。

本記事では XML / JSON Injection の仕組み、危険性、攻撃例、対策 を分かりやすく解説します。


1. XML / JSON Injection とは?

アプリケーションが受け取った JSON または XML をパースし、
そのまま SQL クエリに埋め込むことが原因で発生する注入攻撃 です。

構造化されていても、中身はただの “文字列”
SQL の文脈にその文字列が入り込めば注入が成立します。


2. 典型的な JSON Injection の例

ユーザーが以下の JSON を送信:

{
  "username": "admin' OR '1'='1--",
  "password": "password"
}

アプリがパースした結果:

username = "admin' OR '1'='1--"
password = "password"

そして、もしアプリがこう SQL を生成していたら——

SELECT * FROM users 
WHERE username = 'admin' OR '1'='1'--' 
  AND password = 'password';

結果:

  • OR '1'='1' が常に true
  • コメント -- で後続のパスワード条件が無効化
  • 認証バイパスが成立

= SQL Injection 完全成功


3. XML Injection も本質は同じ

例えば以下の XML:

<login>
  <username>admin' OR '1'='1--</username>
  <password>password</password>
</login>

これをパースして SQL に投入すれば、JSON Injection と同じく攻撃成立。

さらに XML には XXE (XML External Entity) という “外部ファイル読み込み+内部情報漏洩” コンボ脆弱性も存在し、

XML Injection(値の注入)

XXE(ファイル読込/SSRF)

という “二刀流攻撃” の温床にもなります。


4. なぜ起きる?原因まとめ

原因 詳細
① 文字列連結で SQL を組み立てている "SELECT ... WHERE username='" + username + "'" のような組み方
② JSON / XML の入力値を信頼してしまう “構造化されているから安全” は幻想
③ バリデーションが甘い 長さチェック・空文字チェックだけなど
④ Prepared Statement を使用していない パラメータ化されていない SQL は攻撃者の遊び場

構造化データは “整理整頓されている” だけで、安全とは限りません。


5. 攻撃パターン例

パターン1:普通の JSON Injection

{ "username": "admin' OR '1'='1--" }

パターン2:XMLタグ内に SQL 断片を埋め込む

<id>1 OR 1=1</id>

パターン3:JSON 配列を悪用

{
  "roles": ["admin' OR '1'='1--"]
}

パターン4:GraphQL 経由での注入

GraphQL → JSON → 文字列 → SQL
構造が複雑な分、コードの一部が脆弱になりがち。


6. 防御方法(これ守れば 95% 防げる)

1. Prepared Statement / Parameterized Query を必ず使う

SQL の文字列連結は禁止。

Java/Kotlin:

val stmt = conn.prepareStatement(
  "SELECT * FROM users WHERE username = ? AND password = ?"
)
stmt.setString(1, username)
stmt.setString(2, password)

Python:

cursor.execute(
    "SELECT * FROM users WHERE username=%s AND password=%s",
    (username, password)
)

Node.js:

db.query("SELECT * FROM users WHERE username=? AND password=?", [u, p])

2. JSON / XML の値は「信用しない」

  • 形式は正しい
  • 型も正しい
  • でも中身に攻撃 payload がある

→ よくある。

必ずエスケープ/サニタイズを行うこと。


3. XML の場合は XXE を無効化する(必須)

Java の場合:

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

XXE を無効化しないと、
XML Injection + XXE でファイル漏洩 → SQL Injection
のコンボが成立する。


4. ORM / Query Builder を使う

ORM を正しく使えば SQL Injection の発生確率は激減。

ただし、生 SQL を書く部分があればそこは脆弱になるので注意。


まとめ

  • JSON も XML も “構造化されているだけの文字列”
  • 中身を SQL にそのまま渡すと Injection が成立する
  • Prepared Statement を使えばほぼ防げる
  • XML の場合は XXE もセットで対策が必要

「うちは REST API だから大丈夫」
「JSON しか使わないので安全」

こういう油断こそ攻撃者の大好物

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?