Webアプリセキュリティ完全対策ガイド2026|OWASP Top10を実例コードで理解し防御する

OWASP Top 10とは?

OWASP(Open Web Application Security Project)は、Webアプリケーションのセキュリティに関するリスクを年次でランク付けした「OWASP Top 10」を公開しています。2021年版が現在も広く参照されており、すべてのWeb開発者が把握すべき脆弱性リストです。

1. インジェクション攻撃(SQLインジェクション)

最も古典的で危険な攻撃の一つです。ユーザー入力がそのままSQLクエリに埋め込まれると、データベースを不正操作される危険があります。

## 危険なコード(SQLインジェクション脆弱あり)
# Python + SQLiteの悪い例
def get_user_bad(username):
    query = "SELECT * FROM users WHERE username = '" + username + "'"
    # 悪意あるusername: "admin' OR '1'='1" → 全ユーザー取得可能!
    cursor.execute(query)
    return cursor.fetchone()

## 安全なコード(パラメータ化クエリ)
def get_user_safe(username):
    query = "SELECT * FROM users WHERE username = ?"
    cursor.execute(query, (username,))  # バインドパラメータで安全
    return cursor.fetchone()

## ORMを使う(最も安全)
from sqlalchemy.orm import Session
def get_user_orm(db: Session, username: str):
    return db.query(User).filter(User.username == username).first()
    # ORMが自動的にパラメータ化してくれる

2. 壊れた認証(パスワード管理の不備)

## 危険:パスワードを平文やMD5で保存
import hashlib
# NG: MD5はレインボーテーブルで解析可能
hashed = hashlib.md5(password.encode()).hexdigest()

## 安全:bcryptまたはArgon2を使用
import bcrypt
from argon2 import PasswordHasher

# bcryptの使用例
def hash_password(password: str) -> str:
    return bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)).decode()

def verify_password(password: str, hashed: str) -> bool:
    return bcrypt.checkpw(password.encode(), hashed.encode())

# Argon2(より新しくより安全)
ph = PasswordHasher(time_cost=2, memory_cost=65536, parallelism=2)
def hash_password_argon2(password: str) -> str:
    return ph.hash(password)  # Argon2idアルゴリズム使用

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

// 危険:ユーザー入力をそのままHTMLに埋め込む
document.getElementById('output').innerHTML = userInput; // XSS脆弱!

// 安全:textContentを使う(HTMLとして解釈されない)
document.getElementById('output').textContent = userInput;

// React/Vueを使う場合は基本的に安全
// Reactは自動エスケープするため、dangerouslySetInnerHTMLは使わないこと
function SafeComponent({ userInput }) {
  return 
{userInput}
; // 安全:自動エスケープ } // サーバーサイドでのサニタイズ(DOMPurify) import DOMPurify from 'dompurify'; const clean = DOMPurify.sanitize(dirtyHTML); // Python(Flask)でのJinja2テンプレートは自動エスケープ // {{ user_input }} → 安全(自動エスケープ) // {{ user_input | safe }} → 危険!絶対に使わない

4. セキュリティヘッダーの設定

# Nginx設定でのセキュリティヘッダー
# /etc/nginx/conf.d/security.conf

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

# Content Security Policy(CSP)- 最重要
add_header Content-Security-Policy "
  default-src 'self';
  script-src 'self' https://trusted-cdn.com;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  img-src 'self' data: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.yourdomain.com;
  frame-ancestors 'none';
" always;

# HSTS(HTTPSを強制)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

5. CSRF対策

# Django(組み込みCSRF保護)
# settings.py
MIDDLEWARE = [
    'django.middleware.csrf.CsrfViewMiddleware',  # デフォルトで有効
    # ...
]

# テンプレートでのCSRFトークン使用
# {% csrf_token %}

# FastAPIでのCSRF対策
from fastapi import Request, HTTPException
import secrets

def generate_csrf_token():
    return secrets.token_urlsafe(32)

async def verify_csrf_token(request: Request):
    token_header = request.headers.get("X-CSRF-Token")
    token_cookie = request.cookies.get("csrf_token")
    
    if not token_header or not token_cookie:
        raise HTTPException(status_code=403, detail="CSRF token missing")
    
    if not secrets.compare_digest(token_header, token_cookie):
        raise HTTPException(status_code=403, detail="CSRF token invalid")

セキュリティチェックリスト

  • ✅ すべてのSQL・コマンド実行でパラメータ化クエリを使用
  • ✅ パスワードはbcryptまたはArgon2でハッシュ化
  • ✅ HTTPSを強制(HSTSヘッダー設定)
  • ✅ 適切なCSPヘッダーを設定
  • ✅ 依存ライブラリを定期的に更新(npm audit / pip-audit)
  • ✅ エラーメッセージにスタックトレースを含めない(本番環境)
  • ✅ レート制限の実装(ブルートフォース対策)
  • ✅ ログイン試行の監視とアラート設定

まとめ

Webアプリケーションのセキュリティは「一度設定すれば終わり」ではありません。定期的な脆弱性スキャン、依存関係の更新、ペネトレーションテストを実施することが重要です。OWASP Top 10を起点として、自分のアプリケーションのセキュリティを継続的に改善していきましょう。

投稿者 kasata

IT企業でエンジニアとして勤務後、テクノロジー情報メディア「Tech Athletes(テック・アスリート)」を運営。プログラミング、クラウドインフラ(AWS/GCP/Azure)、AI活用、Webサービス開発を専門とする。エンジニア・ビジネスパーソン向けに、実際に使ってみた経験をもとに信頼できる技術情報を発信中。資格:AWS認定ソリューションアーキテクト、Python 3 エンジニア認定試験合格。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です