概要

セキュアコーディングは、脆弱性を開発工程で作り込まないための実装原則・慣行の集合です。SQLi・XSS・バッファオーバーフローなどの典型的な脆弱性はほぼすべて実装の誤りに起因するため、コーディング段階での対処が最も費用対効果が高い対策です。SC試験の午後問題ではソースコードの断片を見て脆弱性を特定・修正する問題が頻出です。

仕組みと動作原理

入力値検証の原則

検証は「入口」と「出口」の両方で行う

タイミング目的
入力時検証(Allowlist)許可した形式以外を拒否電話番号は数字とハイフンのみ
出力時エスケープ文脈に応じてエンコードHTML出力 → HTMLエンティティ変換

許可リスト(Allowlist)vs 拒否リスト(Denylist)

方式説明推奨度
許可リスト明示的に許可した値・形式だけを受け入れる◎ 推奨
拒否リスト既知の危険なパターンを拒否する△ 漏れが生じやすい

拒否リストは攻撃者が新しい迂回手法を使うと無効になるため、可能な限り許可リストを使います。

出力エスケープのコンテキスト

同じ入力値でも出力先によって必要なエスケープが異なります。

出力コンテキストエスケープ方法注意点
HTMLタグ内テキスト& < > " ' → HTMLエンティティデフォルトで必要
HTML属性値上記+属性に応じた処理href は URL の検証も必要
JavaScript\u00XX 形式でUnicodeエスケープHTMLエスケープと異なる
SQLプリペアドステートメントエスケープではなくバインド変数が根本対策
シェルコマンドシェルメタ文字を回避可能な限りシェル呼び出しを避ける

エラー処理の原則

情報漏洩を防ぐエラーハンドリング

# 悪い例(スタックトレースを表示してしまう)
try:
    result = db.query(sql)
except Exception as e:
    return str(e)  # DB構造・ファイルパスが漏洩する

# 良い例
try:
    result = db.query(sql)
except Exception:
    logger.exception("DB query failed")   # 詳細はサーバログへ
    return "エラーが発生しました"           # ユーザには汎用メッセージのみ

エラーメッセージで漏洩しやすい情報:

  • データベースのテーブル名・カラム名(SQLエラー)
  • 内部ファイルパス(例外スタックトレース)
  • ソフトウェアバージョン(Serverヘッダ・エラーページ)
  • 存在するユーザIDの有無(「パスワードが違います」vs「ユーザが存在しません」)

依存ライブラリ(OSS)の管理

サプライチェーン攻撃のリスク

現代のアプリケーションは多数の外部ライブラリに依存しています。直接依存だけでなく、間接依存(依存の依存)にも脆弱性が含まれる可能性があります。

リスク説明対策
既知脆弱性CVEが公開済みのライブラリを使用SCA(ソフトウェア構成分析)ツール
悪意のあるパッケージタイポスクワッティング・乗っ取りパッケージ名の慎重な確認・ロックファイル
メンテナンス停止セキュリティパッチが出なくなる依存ライブラリの定期的な棚卸し
ライセンス違反GPL等の感染性ライセンスライセンス確認ツール

SBOM(ソフトウェア部品表): 使用するすべてのソフトウェアコンポーネントと依存関係を一覧化した文書。脆弱性管理に活用されます。

危険なコーディングパターン

パターンリスク対策
文字列連結でSQL構築SQLインジェクションプリペアドステートメント
innerHTML へのユーザ入力反映XSS(DOM型)textContent を使用
eval() の使用任意コード実行避ける
ハードコードされた認証情報認証情報漏洩環境変数・シークレット管理ツール
平文でのパスワード保存認証情報漏洩bcrypt・Argon2 などの適切なハッシュ
不十分な乱数セッションID予測CSPRNG(暗号学的擬似乱数生成器)を使用

SC試験での頻出ポイント

  • 検証は「入口」ではなく「出口(出力コンテキスト)」が根本対策:SQLi は出力先が SQL なので、SQL 向けのバインド変数が対策
  • エラーメッセージの情報漏洩:攻撃者にシステム内部情報を与えない
  • ハードコードされた認証情報の危険性:Gitリポジトリに含まれると永続的に残る
  • 依存ライブラリの脆弱性管理:Log4Shell(Log4j の脆弱性)のような事例が午後で出題
  • セッションIDの要件:十分なエントロピー・HTTPS 限定・適切な有効期限・ログアウト時の無効化

よくある誤問・ひっかけパターン

誤り① 「フロントエンドで入力値検証していればサーバ側検証は不要」→ 。クライアント側の検証はユーザ体験向上のためのもので、API を直接叩けば回避できます。サーバ側での検証が必須です。

誤り② 「エラーを握りつぶせば安全」→ 。エラーをログに残さずに無視すると障害調査ができなくなります。「ユーザには汎用メッセージ、ログには詳細」が正しいパターンです。

誤り③ 「最新バージョンを使えば脆弱性はない」→ 。新バージョンにも未知の脆弱性(ゼロデイ)が存在し得ます。また直接依存のアップデートが間接依存の脆弱性を解消するとは限りません。

関連用語

重要キーワード

用語説明
許可リスト(Allowlist)明示的に許可した値・形式のみ受け入れる入力検証方式
出力エスケープ出力コンテキスト(HTML・SQL・JS等)に応じた文字エンコード
SBOMソフトウェア部品表。使用する全コンポーネントの一覧
SCAソフトウェア構成分析。依存ライブラリの既知脆弱性を検出するツール
CSPRNG暗号学的に安全な擬似乱数生成器。セッションIDやトークン生成に使用
サプライチェーン攻撃依存ライブラリや開発ツールを通じてアプリケーションに悪意のあるコードを混入させる攻撃