1
2

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

概要

フロントエンドにおけるセキュリティとは、
「攻撃を防ぐこと」ではなく、「壊れない構造を設計すること」である。

XSS、CSRF、セッションハイジャック、トークン漏洩、悪意ある入力…
JavaScriptがユーザーのインターフェースを担う今、クライアント側の設計品質がそのまま防御力となる。

本稿では、JavaScriptにおける代表的な脅威とその対策、
およびUI/UXを壊さずにセキュリティを担保する構造的アプローチを紹介する。


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

// ❌ 危険なパターン:innerHTMLに直接出力
element.innerHTML = userInput;

✅ 解決策:

  • innerText / textContent を使う
  • DOM生成を明示的に構築
const text = document.createTextNode(userInput);
element.appendChild(text);
  • HTMLテンプレートエンジンでは、サニタイズ処理の有無を常に確認

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

  • GETでは副作用のある操作を絶対に許可しない
  • Cookieベースの認証にはSameSite=Strict or Lax を設定
  • 非Cookieベースの認証ではCSRFトークンを埋め込み + サーバーで検証
<input type="hidden" name="csrf_token" value="xxxx">
  • フロントエンドから送信:
fetch('/api/update', {
  method: 'POST',
  headers: {
    'X-CSRF-Token': csrfToken,
  },
});

3. トークン管理:localStorage / sessionStorage / Cookie の選択戦略

保管場所 特性
localStorage 永続。XSSに弱い
sessionStorage タブごと。XSSに弱い
Cookie Secure / HttpOnly / SameSite 可。CSRF対策必須

✅ 原則:

  • XSS対策が万全でなければ Cookie + HttpOnly が最も安全
  • SPAでアクセストークンを扱う場合は、期限 + scope + リフレッシュ設計が必要

4. エスケープと検証の境界戦略

✅ サーバーサイド → サニタイズ済みを前提にしない

✅ クライアント側 → 出力前にescapeHTML

function escapeHTML(str) {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

→ ✅ UI層で必ず**「この値は表示される」ことを想定して防御**する


5. ユーザー入力を介するイベントの設計

  • イベント名 / クラス名 / data属性 にユーザー入力を直接使用しない
// ❌ 危険な例
const el = document.querySelector(`[data-user="${input}"]`);

→ ✅ Mapid-indexセーフな検索手段に分離


6. エラーとロギング:セキュリティ情報の漏洩防止

  • ✅ APIの失敗時にスタックトレース・内部構造を出力しない
  • ✅ ログにアクセストークンや個人情報を含めない
console.error('ユーザー取得に失敗しました'); // ✅ OK
console.error(error.stack); // ❌ 内部構造が露出

設計判断フロー

① 出力箇所にinnerHTMLを使っていないか? → textContentを選択

② トークンがlocalStorageにあり、XSSに晒されていないか? → Cookie + HttpOnlyを検討

③ イベント/属性でユーザー入力を扱っていないか? → DOM設計を再構成

④ トークンや個人情報をconsole.logで出力していないか? → ロギングポリシー設計へ

⑤ CSRF保護が不完全なままCookieを使っていないか? → SameSite/Tokenの導入

よくあるミスと対策

❌ すべての出力にinnerHTMLを使い、XSS攻撃を許容

→ ✅ 表示は textContent、構造は DOM構築で対応


❌ アクセストークンをlocalStorageに永続化し、別ページでも利用可能に

→ ✅ トークンは必要なタイミングでメモリ保持 + 期限管理 or HttpOnly Cookie


❌ fetch時にCSRFトークンを含め忘れ、保護バイパスが可能に

→ ✅ API設計時にトークン含有をデフォルト設計


結語

セキュリティとは「攻撃をブロックする」ことではない。
それは**「攻撃される前提で設計する」こと**である。

  • 表示前に必ず疑い
  • イベント前に経路を遮断し
  • 情報が漏れることを想定して制御する

JavaScriptにおけるセキュリティ設計とは、
“フロントエンドが最後の砦であることを理解した構造の構築”である。

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?