aws-samples / aws-samples/serverless-full-stack-webapp-starter-kit

security(webapp): 兄弟サブドメインからの CSRF を防ぐため Server Actions の allowedOrigins を厳格化する

Aperta
#210 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub
enhancement needs-triage security
Lingua principale
TypeScript
Stelle
229
Fork
45
Merge medio
1m
PR unite (30g)
4

Descrizione

executor 07(全コードベースのコードレビュー)が発見し、独立したセキュリティレビュー(サブエージェント, opus-4.7)で裏付けた。

## 問題

`apps/cdk/lib/constructs/webapp.ts` は Docker ビルド引数 `ALLOWED_ORIGIN_HOST` を、カスタムドメイン分岐では `*.${hostedZone.zoneName}` に(CloudFront デフォルト分岐では `*.cloudfront.net` に)設定している。その値は `apps/webapp/next.config.ts` に取り込まれ、`experimental.serverActions.allowedOrigins` に渡される。

`serverActions.allowedOrigins` は CORS リストではなく、Next.js のデフォルトの CSRF 保護(Origin/Host の一致)を抑制する許可リストである。ワイルドカードを追加すると、そのホストゾーンの任意の兄弟サブドメイン(アプリが所有していない、新規登録された、乗っ取られた、他テナントと共有されているサブドメインを含む)が同一アプリのオリジンとして扱われ、認証済みの Server Actions をアプリに対して送信できてしまう。兄弟サブドメインは same-site であるため、`SameSite=Lax` クッキーではこれを防げない。

`*.cloudfront.net` のフォールバックはさらに悪く、インターネット上の _すべての_ CloudFront ディストリビューションを信頼された CSRF オリジンにしてしまう。

一次情報: https://nextjs.org/docs/app/api-reference/config/next-config-js/serverActions (Server Actions allowedOrigins / 組み込みの CSRF 保護)。

## 根拠

- `apps/cdk/lib/constructs/webapp.ts:80` — `ALLOWED_ORIGIN_HOST: hostedZone ? \`_.${hostedZone.zoneName}\` : '_.cloudfront.net'`
- `apps/webapp/next.config.ts:3-18` — ビルド引数から `allowedOrigins` を構築。

## 対応の方向性(要議論)

- カスタムドメイン分岐: 具体的なホスト(`${subDomain}.${hostedZone.zoneName}`、現状は `web.${zone}`)を渡し、ブラウザの Origin と一致させる。
- CloudFront デフォルト分岐: ドメインはデプロイ時に判明し、Lambda ↔ CloudFront の循環依存を生む(コード内で既に文書化済み)ため、「正確なホストを渡すだけ」では不十分。検討する選択肢: (a) デフォルトの `same-origin` 挙動を受け入れ、ビルド引数を完全に削除する(同一ホストから送信される Server Actions は Origin/Host 一致で成功する); (b) `AMPLIFY_APP_ORIGIN_SOURCE_PARAMETER` を既に更新している既存の `AwsCustomResource` を通じて、実行時に `ALLOWED_ORIGIN_HOST` を更新する。

この修正はエンドツーエンド(Lambda Function URL のレスポンスストリーミング → Next.js Server Actions を通じた `x-forwarded-host` の伝播)で検証する必要があるため、盲目的にマージするのではなく議論用の issue として起票する。

## サンプルとしての教育的リスク

このサンプルは、`allowedOrigins` をあたかも寛容な CORS リストであるかのように設定することを新規ユーザーに教えてしまう。コピーしたアプリが `beta.${zone}` や実験的なサブドメインを追加すると、同一ホストゾーンの任意のサブドメインに対する暗黙の信頼を引き継ぐ。

## 関連

- executor 07 の発見まとめ: `.kiro/specs/v3-release-prep/review-full-report.md` (H2)
- #173 の重複ではない(あちらはセッションキャッシュに関するもので CSRF ではない)。

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Leggi apps/cdk/lib/constructs/webapp.ts e apps/webapp/next.config.ts per tracciare come ALLOWED_ORIGIN_HOST viene trasferito in serverActions.allowedOrigins; esamina anche .kiro/specs/v3-release-prep/review-full-report.md. Decidi la strategia per il dominio personalizzato e CloudFront, quindi convalida tramite lo streaming delle risposte di Lambda Function URL e le Next.js Server Actions che vengano accettate solo le origini previste.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
aws, nextjs, typescript
Ambito
backend, infrastructure, security
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.