こんにちは。セキュリティの世界へようこそ。
日々、見えない場所で繰り広げられる攻防戦を指揮している身として、今日は皆さんに「APIの玄関口を守る」という、非常に重要かつ泥臭いけれど面白いお話をしようと思います。
「セキュリティ」と聞くと、RSAやAESといった難しい暗号の数式を思い浮かべるかもしれません。でも、実際の現場で最も多く発生する事故は、もっと身近な「泥棒の侵入」と同じなんです。
—
家の鍵と「APIの玄関口」
想像してみてください。あなたの家には頑丈な鍵(認証)がかかっています。でも、窓が全開だったり、玄関のポストから細い棒を突っ込んで鍵を開けられる状態だったらどうでしょう?
APIにおける「JSONデータ」は、まさにあなたの家の「ポスト」や「郵便受け」です。攻撃者は、この郵便受けの中に、爆発物や怪文書(不正なデータ)を放り込んで、家の中をめちゃくちゃにしようとします。
私たちがこれから学ぶ「入力バリデーション」と「スキーマ検証」は、「ポストの口に、郵便物以外の変なものが入らないようにフィルターをかける」という防犯対策なんです。
—
なぜ「型」や「構造」を疑う必要があるのか?
新人の開発者が一番やりがちなミスは、「ユーザーは正しいデータを送ってくれるはずだ」と信じてしまうことです。残念ながら、インターネット上にいる攻撃者は、あなたの期待を裏切るのが仕事です。
例えば、年齢を入力するフォームに「1000歳」と入れたり、名前を入力する場所に「 <script>alert('ハックしたよ')</script>」のような、悪意のあるプログラムコードを送り込んできたりします。
もし、これをそのままデータベースに入れてしまったら? システムは「あ、これプログラムだな。実行しなきゃ!」と勘違いして、攻撃者の指示通りに動いてしまいます。これがインジェクション攻撃の入り口です。
—
「JSON Schema」で玄関に番人を置こう
APIで受け取るデータの「型(数値なのか文字列なのか)」や「構造(どんな項目が含まれているか)」を厳格に決めておくのが「JSON Schema」です。
「身長は100から250までの数値じゃないとダメですよ」「名前は50文字以内の文字列ですよ」と、あらかじめルールを決めておくのです。このルールに合わないデータが来たら、玄関で門前払いする。これが最も効率的な防御策です。
実践:Node.jsでのスキーマ検証例
例えば、ユーザー登録のAPIで名前と年齢を受け取る場合、以下のように定義します。
// 検証用ライブラリ(ajvなど)を使った例です
const schema = {
type: "object",
properties: {
username: { type: "string", maxLength: 50 }, // 文字列で50文字まで
age: { type: "integer", minimum: 0, maximum: 150 } // 0〜150の数値のみ許可
},
required: ["username", "age"], // この項目がないと受け付けない
additionalProperties: false // 定義していない余計な項目は弾く!
};
// 攻撃者が年齢のところに「文字列」や「ありえない数字」を入れても、
// この番人が「ルール違反です!」と即座に弾いてくれます。
additionalProperties: false という設定が地味に見えて実は最強です。攻撃者が「ついでに管理者権限を書き換えよう」と余計なデータを送り込んできても、この設定さえあれば「そんな項目は聞いていない!」とシャットアウトできるからです。
—
セキュリティの「泥臭い」現場から
皆さんに一つだけ覚えて帰ってほしいことがあります。それは、「境界線」を意識することです。
システム内部のプログラムは、外部から来たデータを信用してはいけません。たとえ自社で作った他のシステムからの通信であっても、「外部から来たものはすべて泥棒かもしれない」という疑いを持つこと。これが、最高峰のセキュリティエンジニアが常に守っている鉄則です。
1. 型を厳格にする: 数値なら数値、文字列なら文字列と決めつける。
2. 範囲を決める: 長さや値の範囲を制限する。
3. 余計なものは受け取らない: 定義外のデータは容赦なく捨てる。
これだけで、巷に溢れるインジェクション攻撃の9割は防げます。
—
最後に:完璧を目指さない勇気
セキュリティに「100%の安全」はありません。どれだけ頑丈な鍵をかけても、鍵そのものを盗まれたら終わりだからです。だからこそ、私たちは「多層防御」といって、玄関の鍵だけでなく、窓に格子をつけ、家の中に監視カメラを置くように、何重もの対策を重ねていきます。
まずは今日、あなたが書いているAPIのコードを一度見直してみてください。「このデータ、もし攻撃者がめちゃくちゃな値を送ってきたらどうなるかな?」と想像するだけで、あなたはもう立派なセキュリティエンジニアの卵です。
一歩ずつ、確実に。泥臭い積み重ねが、あなたのサービスを、そしてユーザーの生活を守る最強の盾になるはずですよ。
コメント