こんにちは!インフラやセキュリティの世界へようこそ。
初めてセキュリティの勉強をすると、見たこともない難しい用語がたくさん出てきて、「自分に使いこなせるかな……」と不安になりますよね。でも、安心してください。セキュリティの基本は、私たちが普段暮らしている「現実世界の防犯」とまったく同じなんです。
今回は、Webシステムの最前線で活躍する「API Gatewayにおけるリクエストバリデーション(JSONスキーマを用いた構造検証)」について、おうちの防犯にたとえながら、一歩ずつ優しく紐解いていきたいと思います。
実務でそのまま使える設定サンプルも用意したので、一緒にマスターしていきましょう!
—
1. 泥棒の侵入を防ぐ!API Gatewayは「自宅の玄関」
まずは、Webシステムがどうやって動いているか、イメージしてみましょう。
皆さんがスマートフォンアプリやWebサイトを使うとき、裏側では「サーバー」というコンピューターがデータを受け渡ししています。このサーバーの玄関口に立っているのが、今回主役になる「API Gateway(APIゲートウェイ)」です。
玄関の鍵をかけ忘れていませんか?
もし、このAPI Gatewayという玄関に「鍵」がかかっておらず、誰でも自由に出入りできる状態だったらどうなるでしょうか?
悪意のある攻撃者(泥棒)がやってきて、こんなことをするかもしれません。
「おっ、この玄関はチェックが甘いぞ。中身が空っぽの変な荷物を大量に放り込んで、家の中をめちゃくちゃにしてやれ!」
バックエンド(奥の部屋にいるサーバーやデータベース)まで変なデータが届いてしまうと、システム全体がダウンしてしまったり、大切なデータが盗まれたりしてしまいます。
だからこそ、「玄関の扉(API Gateway)のところで、怪しい荷物は徹底的にチェックして追い返す」ことが、セキュリティの第一歩なんです。
—
2. 不正なペイロード(荷物)がもたらす脅威
ここで言う「荷物」とは、アプリからサーバーへ送られるデータ(専門用語でペイロードやリクエストボディと言います)のことです。現代のWebでは、このデータの形式としてJSON(ジェイソン)というルールがよく使われます。
攻撃者は、このJSONの仕組みを悪用して、以下のような攻撃を仕掛けます。
1. 想定外のバカでかいデータを送りつける:サーバーの記憶容量をパンクさせる(DoS攻撃)。
2. プログラムの仕掛け(悪意あるスクリプト)を忍ばせる:データを保存するデータベースを乗っ取る(インジェクション攻撃)。
3. ルール違反の変な項目を混ぜる:年齢を入れる欄に文字を入れるなどして、システムを混乱させる。
これらをすべて奥の部屋(バックエンド)まで通してしまうのは、鍵の開いた玄関に知らない人を招き入れるようなもの。非常に危険ですよね。
—
3. JSONスキーマとは?「荷物のサイズ・形状チェックリスト」
ここで登場するのが、今回のテーマのキモである「JSONスキーマ(JSON Schema)」です。
JSONスキーマとは、一言で言うと「届いた荷物が、あらかじめ決められた正しい形・サイズ・中身をしているか厳しくチェックするための仕様書(チェックリスト)」のことです。
例えば、オンラインショップで「ユーザー登録」をするとき、サーバーが受け取るデータは以下のようなルールであってほしいですよね。
- 名前 (
name) は文字で、必ず入っていなければならない。 - 年齢 (
age) は数字で、0歳から120歳の間でなければならない。 - メアド (
email) はメールアドレスの形をしていなければならない。
API Gatewayにこの「JSONスキーマ」というチェックリストを持たせておけば、アプリから送られてきたデータが基準を満たしているか、玄関先で一瞬にして判定できるようになります。
もし、ルール違反のデータがあれば、「この荷物はルール違反なので、中には通せません!」と、バックエンドに届く前にピシャリと追い返す(遮断する)ことができるのです。これが「リクエストバリデーション」の仕組みです。
—
4. 【実践】API Gatewayでの設定とコード例
「概念は分かったけれど、実際にどう設定するの?」という声にお応えして、AWSなどのクラウドサービスでよく使われるJSONスキーマの具体例を見てみましょう。
今回は、ユーザー登録API(POST /users)を想定した、シンプルなJSONスキーマのサンプルです。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "UserRegistrationRequest",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 50,
"description": "ユーザーの氏名(1文字以上50文字以下)"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 120,
"description": "年齢(0歳から120歳まで)"
},
"email": {
"type": "string",
"format": "email",
"description": "連絡先のメールアドレス"
}
},
"required": ["name", "email"],
"additionalProperties": false
}
コードの解説(ここがポイント!)
"type": "object": 届いたデータが、波括弧{}で囲まれたオブジェクト形式であることを確認します。"required": ["name", "email"]:nameとemailは絶対に省略してはいけない項目(必須項目)に指定しています。もしこれが抜けていたら、その場でエラーになります。"additionalProperties": false: ここがセキュリティ上、非常に重要なポイントです!あらかじめ決められた項目(name,age,email)以外の余計なデータ(攻撃者がこっそり混ぜた不正なパラメータなど)が含まれている場合、すべて拒否します。玄関の検査で「申告外の怪しい荷物」を一切通さないための強力な門限ルールです。
—
5. 防御ヘッダーの役割と、現場での泥臭い知見
API Gatewayでバリデーションを行う際、HTTP通信のルールである「ヘッダー」にも少しだけ気を配る必要があります。
特に重要なのが、リクエストを送る側が「今から送る荷物はJSON形式ですよ」と教えてあげるためのヘッダーです。
Content-Type: application/json
もし、攻撃者がこの Content-Type を偽って、中身がぐちゃぐちゃのテキストデータを送り込んできた場合、API Gateway側で「あれ、これJSONじゃないな」と弾けるように設定しておくことが、現場のインフラエンジニアとしての腕の見せ所です。
現場のエンジニアが語る「泥臭い」落とし穴
教科書には「バリデーションをかければ完璧!」と書かれていますが、実際の現場では少し違います。
1. スキーマが厳しすぎて、アプリ側のアップデートと噛み合わずにシステムが壊れる(自爆事故)
- 新機能で「電話番号」の項目を追加したのに、API GatewayのJSONスキーマを更新し忘れて、正当なユーザーの登録まで弾いてしまった……というのは、現場でよくある冷や汗もののトラブルです。
2. エラーメッセージを親切にしすぎない
- 不正なリクエストを弾いたときに、詳細すぎるエラー(例:
Database error at line...など)を返してしまうと、攻撃者にヒントを与えてしまいます。「入力内容に不備があります」程度にとどめるのが、セキュリティの鉄則です。
—
まとめ
今回は、API Gatewayにおけるリクエストバリデーションについて、おうちの玄関の防犯にたとえて解説しました。
- API Gateway はシステムの「玄関」。
- JSONスキーマ は荷物の「サイズ・形状チェックリスト」。
- バックエンドにゴミや攻撃データを届かせないために、玄関のところで厳しくチェックして遮断することが何よりも大切。
セキュリティ対策と聞くと難しく身構えてしまいますが、「怪しいものは家に入れない」という基本の積み重ねです。一つひとつの仕組みを丁寧に紐解いていけば、誰でも頼れるセキュリティ担当者になれますよ。
今日の学びを、ぜひ皆さんの開発やインフラ構築の現場に活かしてみてくださいね!
コメント