
「TypeScriptを使っているから安全」
そう思っていませんか?
型安全は確かに強力です。しかし、エッジ環境(Edge Runtime・CDN実行基盤)で動くアプリケーションでは、従来のサーバー設計とは異なるセキュリティリスクが存在します。
結論から言えば、型だけでは守れません。
実行時検証・ゼロトラスト設計・ヘッダー制御まで含めて初めて、安全な構成になります。
本記事では、TypeScript × エッジ環境における実装レベルのセキュリティ対策を、具体例とともに整理します。
TypeScriptはセキュリティを保証するのか?
結論
TypeScriptは「型安全」を提供しますが、「実行時の安全性」は保証しません。
理由
- 型情報はコンパイル時のみ存在
- 実行時はJavaScriptとして動作
- 外部入力は常に未知
つまり、型チェックは「開発時の安全」であり、「攻撃耐性」ではありません。
メリット
- バグ削減
- IDE補完による設計精度向上
- 大規模開発の安定化
デメリット
- 実行時検証は別途必要
- API境界での不正入力は防げない
実装例:ランタイム検証(Zod)
import { z } from "zod";
const UserSchema = z.object({
email: z.string().email(),
age: z.number().min(0),
});
export function validate(input: unknown) {
return UserSchema.parse(input);
}
APIの入り口では必ずランタイム検証を行う。
これが最初の防御線です。
エッジ環境特有のセキュリティ特性
エッジランタイム(例:Vercel Edge・Cloudflare Workersなど)には特徴があります。
特徴
- Node.js APIが使えない
- 軽量VMで高速実行
- 地理的に分散配置
メリット
- レイテンシ削減
- DDoS耐性向上
- グローバル分散防御
デメリット
- ログ収集が分散
- セッション設計が難しい
- デバッグが複雑
注意点
- JWT検証は毎リクエスト実施
- CookieはHttpOnly必須
- SameSite=Lax以上推奨
import { jwtVerify } from "jose";
export async function verify(token: string) {
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
return jwtVerify(token, secret);
}
エッジでの認証設計
基本原則
- ステートレス設計
- トークン短命化
- 最小権限
推奨構成
- アクセストークン:15分以内
- リフレッシュトークン:HTTPOnly Cookie
- ローカルストレージ保存は避ける
リスク
- XSSによるトークン窃取
- CORS設定不備
- 不適切なキャッシュ
実際にローカルストレージ保存を廃止し、HTTPOnly Cookieへ移行しただけでXSSリスクは大きく下がります。
CSP・セキュリティヘッダー実装
Content Security Policyは必須レベルです。
代表的ヘッダー
- Content-Security-Policy
- X-Content-Type-Options
- X-Frame-Options
- Strict-Transport-Security
export const config = {
runtime: "edge",
};
export default function middleware() {
return new Response(null, {
headers: {
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
},
});
}
メリット
- XSS防止
- クリックジャッキング対策
- MIME偽装防止
デメリット
- 設定ミスで動作停止
- 外部スクリプト制限が厳しい
ゼロトラスト設計の考え方
原則
- すべての入力を疑う
- 内部通信も検証する
- 権限は最小限に
実装例
- APIごとに認可チェック
- ロールベースアクセス制御
- 環境変数の厳格管理
特にエッジ環境では、環境変数の公開範囲を誤ると即情報漏洩につながります。
ログ・監査戦略
エッジではログが分散するため設計が重要です。
必須対策
- 集中ログ基盤へ転送
- 認証失敗は必ず記録
- 異常アクセスを監視
注意点
- 個人情報はログに残さない
- 法令遵守を前提に保存期間を決定
実装チェックリスト
- API入力にランタイム検証を入れているか
- JWTは短命化しているか
- CookieはHttpOnlyか
- CSPを設定しているか
- 環境変数は公開されていないか
- ログは集中管理されているか
まとめ
TypeScript × エッジは非常に強力な構成です。
しかし、安全は「型」ではなく「設計」で決まります。
重要なのは:
- 型安全+ランタイム検証
- ゼロトラスト設計
- ヘッダー制御
- 最小権限
- ログ監視
今すぐ、API入口とCookie設定を見直してください。
高速なエッジ環境だからこそ、防御設計は慎重に行う必要があります。
型安全に安心しがちな今だからこそ、実行時防御まで含めた設計へ切り替えることが、これからの開発において最も現実的で効果的な一歩になります。