2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるセキュリティ設計:XSS・CSRF・入力検証・セキュアなコード構造の戦略的対策

Posted at

概要

セキュリティとは“後から足すもの”ではない。
それは設計段階から織り込むべき構造的防御力であり、書かれていないコードにも責任が発生する領域である。
本稿では、JavaScriptにおける代表的な脆弱性とその防止策を、開発・設計・運用それぞれの観点から整理する。


1. XSS(クロスサイトスクリプティング)

✅ 症状:ユーザー入力をHTMLやDOMに直接埋め込む

element.innerHTML = userInput; // ❌ 危険

→ 攻撃者による <script>alert('XSS')</script> などの注入が可能に


✅ 対策:

  • textContent を使う(エスケープ済み)
  • innerHTMLを使う場合、信頼されたテンプレートのみ
  • サーバー側で Content Security Policy(CSP) を設定
  • フレームワークのテンプレートは自動エスケープされるか確認
element.textContent = userInput; // ✅ 安全

2. CSRF(クロスサイトリクエストフォージェリ)

✅ 症状:認証済みユーザーの代わりに意図しないリクエストが送られる


✅ 対策:

  • サーバー側で SameSite Cookie を有効に設定
  • CSRFトークン(ランダム値)をHTMLに埋め込み、POST時に送信
  • 認証付きAPIは トークンベース(JWTなど)で制御
<input type="hidden" name="csrf_token" value="ランダム値">

→ ✅ クライアント側でもトークン付加を忘れず送信


3. 入力検証とサニタイズ

✅ 症状:信頼しない入力値をそのまま利用(DOM・SQL・APIなど)

const query = new URLSearchParams(location.search);
const userId = query.get('user_id'); // ❌ 検証なし

✅ 対策:

  • 数値チェック → Number.isInteger()
  • メール → RegExp + メール形式検証
  • 文字列長・禁止記号チェック
  • DOMPurify などのライブラリでHTMLサニタイズ
if (!/^[a-z0-9]{1,20}$/.test(userId)) {
  throw new Error('不正なID');
}

→ ✅ 入力は信頼できない前提で扱う


4. 安全な通信とHTTPS強制

  • 常時HTTPS(ローカルでも localhost 専用証明書を使う設計)
  • fetch() 使用時はプロトコル確認(HTTPS外はブロック)
  • Secure, HttpOnly, SameSite を付けたCookieで通信制御

5. セキュアなストレージ設計

  • localStorage → 永続、XSSに弱い(避ける or 最小限)
  • sessionStorage → タブ間非共有
  • IndexedDB → 大容量データの保持
  • 機密情報(トークンなど)はJS側に残さない設計が望ましい

6. セキュリティ設計の構造原則

原則 意味
最小権限の原則(POLP) 必要最小限の操作だけを許す
明示的な許可 デフォルトは「禁止」、許可されたものだけ通す
失敗時の安全設計 想定外の入力・エラー時は、安全側に倒す
表層と構造の分離 表示のHTML/CSSとロジックを分け、攻撃面を削減
ログと監査の明示 エラーや操作の記録は常に検出可能な形で残す

設計判断フロー

① ユーザー入力をDOMに表示? → textContent or エスケープ必須

② 通信にCookieを使っている? → SameSite/CSRF対策を確認

③ 入力値を使ってAPIやSQL呼び出し? → 検証と正規化を導入

④ 通信はHTTPSか? → fetch/axiosなどでプロトコル強制

⑤ 状態やトークンを保存? → ストレージの選定とアクセス制限を設計

よくあるミスと対策

❌ innerHTMLで出力するが、入力にエスケープがない

→ ✅ 表示内容とロジックを分離し、textContentやテンプレートで制御


❌ Cookieベースの通信でSameSiteを未指定

→ ✅ SameSite=Lax or Strictを明示


❌ サーバー側でCSRF対策があるが、フロントからトークン未送信

→ ✅ fetchaxiosCSRFトークンをヘッダーに付加


結語

セキュアなコードとは、**“攻撃されても壊れない構造を設計すること”である。
それは単なるルールではなく、
「信頼できないものを信頼しない設計習慣」**の集合である。

  • UIの裏にあるリスクを知り
  • 通信の先にある責任を持ち
  • 書かないコードにも防御を施す

攻撃は常に外からやってくる。
防御は、常にコードの中で始まっていなければならない。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?