サイバー攻撃が年々高度化する2026年、エンジニアとして知っておくべきセキュリティの基礎知識と実践的な対策を完全解説します。OWASP Top 10から始まり、認証・認可設計、SQLインジェクション対策、XSS対策まで実装コード付きで解説します。
OWASP Top 10(2021)完全解説
- A01: アクセス制御の不備 – 認証・認可の実装ミス
- A02: 暗号化の失敗 – 機密データの平文保存・弱い暗号化
- A03: インジェクション – SQLi、コマンドインジェクション
- A04: 安全でない設計 – セキュリティ設計の欠如
- A05: セキュリティの設定ミス – デフォルト設定の使用
- A06: 脆弱なコンポーネント – 古いライブラリの使用
- A07: 認証・セッション管理の不備 – 弱いパスワード・セッション固定
- A08: ソフトウェアとデータの整合性の失敗 – CI/CDパイプラインのセキュリティ
- A09: セキュリティのログ・監視の不備 – 攻撃の検知不能
- A10: サーバーサイドリクエストフォージェリ(SSRF)
SQLインジェクション対策
# ❌ 危険:文字列結合でSQLを構築
def get_user_bad(username: str):
query = f"SELECT * FROM users WHERE username = '{username}'"
# username = "admin' OR '1'='1" のような攻撃が可能!
return db.execute(query)
# ✅ 安全:プリペアドステートメントを使用
def get_user_safe(username: str):
query = "SELECT * FROM users WHERE username = ?"
return db.execute(query, (username,)) # パラメータは自動エスケープ
# ✅ ORMを使用(推奨)
from sqlalchemy.orm import Session
def get_user_orm(db: Session, username: str):
return db.query(User).filter(User.username == username).first()
XSS(クロスサイトスクリプティング)対策
// ❌ 危険:innerHTML でユーザー入力を直接表示
const userInput = "<script>alert('XSS!'</script>";
document.getElementById('output').innerHTML = userInput; // 危険!
// ✅ 安全:textContent を使用
document.getElementById('output').textContent = userInput; // エスケープされる
// ✅ DOMPurifyでサニタイズ(HTMLを表示する必要がある場合)
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userInput);
document.getElementById('output').innerHTML = clean;
// ✅ Content Security Policy (CSP) ヘッダーの設定
// nginx.conf
// add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-RANDOM_NONCE';";
認証・認可の安全な実装
import bcrypt
import secrets
from datetime import datetime, timedelta
import jwt
# パスワードのハッシュ化(bcrypt推奨)
def hash_password(password: str) -> str:
salt = bcrypt.gensalt(rounds=12) # 12ラウンドは2026年推奨値
return bcrypt.hashpw(password.encode(), salt).decode()
def verify_password(password: str, hashed: str) -> bool:
return bcrypt.checkpw(password.encode(), hashed.encode())
# JWTトークンの生成
def create_access_token(user_id: int, secret_key: str) -> str:
payload = {
"sub": str(user_id),
"exp": datetime.utcnow() + timedelta(hours=1),
"iat": datetime.utcnow(),
"jti": secrets.token_urlsafe(16) # JWT ID(リプレイ攻撃対策)
}
return jwt.encode(payload, secret_key, algorithm="HS256")
# CSRFトークン
def generate_csrf_token() -> str:
return secrets.token_urlsafe(32)
セキュリティチェックリスト
| カテゴリ | チェック項目 | 優先度 |
|---|---|---|
| 認証 | パスワードはbcrypt等でハッシュ化 | 🔴 必須 |
| 認証 | 多要素認証(MFA)の実装 | 🔴 必須 |
| 通信 | HTTPS(TLS 1.2+)の強制 | 🔴 必須 |
| 入力検証 | すべての入力値のバリデーション | 🔴 必須 |
| 依存関係 | 定期的なnpm audit / pip audit | 🟡 重要 |
| ヘッダー | セキュリティヘッダーの設定(CSP, HSTS) | 🟡 重要 |
| ログ | 認証失敗・異常アクセスのログ記録 | 🟡 重要 |
| シークレット | APIキー・パスワードを環境変数で管理 | 🔴 必須 |
セキュリティは後から追加するのではなく、設計段階から組み込む「セキュリティ・バイ・デザイン」の考え方が重要です。定期的なコードレビュー、依存関係の更新、ペネトレーションテストを実施して継続的にセキュリティを改善しましょう。