【実務・中級編】APIの入力バリデーション:JSONスキーマによる厳格な型チェック – アプリケーションセキュリティ & 安全な開発防御ガイド

JSONスキーマでXSSを根絶する:Web APIの入力バリデーションという「防波堤」

やあ、現場の最前線でコードと格闘しているエンジニア諸君。セキュリティの現場にいると、毎日数え切れないほどの「なぜこれが通ってしまったのか」というインシデントログを眺めることになる。

多くのエンジニアが「XSS(クロスサイトスクリプティング)」と聞くと、 をフォームに打ち込む反射型攻撃を想像しがちだ。しかし、現代のAPI中心のアーキテクチャにおいて、真の脅威は「想定外のJSON構造」に潜んでいる。

今日は、フロントエンドへ渡されるデータをAPIの入り口で遮断する「JSONスキーマによる厳格なバリデーション」という、泥臭いが最も効果的な防御術を叩き込む。

—

1. なぜ「JSONスキーマ」がXSSの特効薬なのか

JSONは柔軟だ。しかし、その柔軟さが仇となる。攻撃者はAPIに対し、定義されていないフィールドを混入させたり、期待されている文字列型(String)の場所に配列(Array)やオブジェクト(Object)を投げ込んだりして、クライアント側の処理をバグらせる。

もし、フロントエンドのJSライブラリが「入力されたJSONの構造を信じ切って」DOM操作を行っていたらどうなるか? 攻撃者はJSONの構造を歪めることで、意図しない場所でスクリプトを実行させる「DOM型XSS」のトリガーを引くことができるんだ。

「バリデーションはフロントエンドでやるもの」と考えているなら、今すぐその考えを捨てろ。APIサーバーが受け取るJSONは、必ず厳格なスキーマで「ホワイトリスト」形式で検証する。 これが鉄則だ。

—

2. 実践:Python (FastAPI) でJSONスキーマを強制する

FastAPIはPydanticという強力なバリデーションライブラリと親和性が高い。これを使えば、型チェックとバリデーションを数行で実装できる。

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, validator
import re

app = FastAPI()

スキーマ定義:余計なフィールドを排除(forbid)し、厳格に定義する
class UserProfile(BaseModel):
# Fieldを使って文字数制限や正規表現を適用し、インジェクションの芽を摘む
username: str = Field(…, min_length=3, max_length=20, pattern=”^[a-zA-Z0-9]+$”)
bio: str = Field(…, max_length=200)

class Config:
# 厳格モード:スキーマにないフィールドが来たら即座にエラー
extra = ‘forbid’

@app.post(“/update-profile”)
async def update_profile(profile: UserProfile):
# ここまで到達したデータは、型も長さも形式も保証されている
return {“status”: “success”, “data”: profile}

実践Tips:
不正なデータが送られてきた場合、FastAPIは自動的に422 Unprocessable Entityを返す。
これを攻撃者が触れないように、グローバルな例外ハンドラで詳細なエラー内容を漏らさないように調整しろ。

—

3. なぜこれでXSSが防げるのか?(攻撃者の視点)

攻撃者が {"username": "

securityintronationalをフォローする

コメント

タイトルとURLをコピーしました