---
title: "セキュアコーディングとは？10原則と主要脆弱性のコード対策を実装目線で解説"
url: "https://www.issoh.co.jp/column/details/2373/"
published: 2024-06-07
updated: 2026-10-12
categories: ["セキュリティ"]
publisher: "株式会社一創"
---

# セキュアコーディングとは？10原則と主要脆弱性のコード対策を実装目線で解説

セキュアコーディングとは、ソフトウェアの設計・実装・保守の各工程で脆弱性を作り込まないことを目的としたプログラミング手法である。機能を満たすだけの「動くコード」と違い、攻撃者が入力・境界・権限をどう悪用するかを想定し、その侵入経路を閉じながらコードを書く点が本質になる。この記事では、SEI CERTの10原則、OWASP Top 10 2025年版に沿った脆弱性別のコード対策、参照すべき標準の現在地、言語別の注意点、既存プロジェクトへの導入手順、AI生成コードのレビュー観点までを実装目線で整理する。

## まとめ：セキュアコーディングとは何かと最初に押さえる3原則

- セキュアコーディングの核心は**「信頼できない入力を検証し、他システムへ渡すデータを無害化し、既定で拒否する」**こと。個別の攻撃名を覚える前にこの3点を徹底する。
- 実装の指針は米カーネギーメロン大SEI CERTの**「Top 10 Secure Coding Practices（10原則）」**に集約される。入力検証・最小権限・多層防御などが柱。
- SQLインジェクションは**プレースホルダ（プリペアドステートメント）**、XSSは**出力時のエスケープとCSP**で塞ぐ。文字列連結でクエリやHTMLを組み立てないことが最優先。
- 優先順位は**OWASP Top 10 2025年版**で決める。第1位はアクセス制御の不備（A01）で、寄せられたテストデータでは平均3.73％のアプリケーションに該当する弱点が見つかっている。
- 2025年版では**サプライチェーンの不備（A03）と例外処理の不備（A10）が新設**された。自作コードの外側と異常系の書き方が新しい主戦場になっている。
- 人手のレビューだけでは漏れる。SAST（静的解析）・DAST（動的診断）・依存ライブラリ検査をCI/CDに組み込み、継続的に検出する。

## セキュアコーディングの定義と通常のコーディングとの実装上の違い

セキュアコーディングは、データの機密性・完全性・可用性を守るために、脆弱性の作り込みを開発段階で防ぐコーディングを指す。「セキュアプログラミング」もほぼ同義で使われる。押さえておきたいのは、脆弱性の修正コストが工程の下流ほど跳ね上がる点だ。IPAやマイクロソフトのSDL（Security Development Lifecycle）が繰り返し示すように、実装段階で作り込みを防ぐほうがリリース後の対応より桁違いに安く済む。

通常のコーディングが「正しい入力が来たときに正しく動くこと」を目標にするのに対し、セキュアコーディングは**「不正な入力・想定外の状態が来たときに安全側に倒れること」**を目標にする。たとえば通常実装では入力チェックを省いても機能は動くが、セキュアコーディングでは境界（外部入力・API・ファイル）を信頼せず検証する。この「悪意ある入力を前提に境界を設計する」姿勢が両者を分ける。

個人の書き方の問題で終わらせると定着しない。検証をパイプラインへ組み込み、開発プロセス全体で担保する考え方が[DevSecOpsとDevOpsの違いを整理した記事](/tech/details/13538/)で扱っている領域にあたる。セキュアコーディングはその一番内側、コードを書く手つきの部分を指す。

## セキュアコーディングの10原則とSEI CERTが示す優先順位の付け方

断片的な対策を並べる前に、原則から入ると全体像がぶれない。世界的に参照されるのが、米カーネギーメロン大学SEI（Software Engineering Institute）のCERT部門がまとめた「Top 10 Secure Coding Practices」だ。言語に依存しない指針で、国内の解説記事が挙げる「10個の原則」もこれを下敷きにしている。

- **1\. 入力を検証する**：コマンド引数・ネットワーク・環境変数・ファイルなど、信頼できない全入力を長さ・型・範囲・形式で検証する。
- **2\. コンパイラ警告を解消する**：最高警告レベルでコンパイルし、可能なら警告をエラー扱いにする。
- **3\. セキュリティ方針を設計に織り込む**：認証・認可・監査の方針を、後付けでなく設計段階から組み込む。
- **4\. 設計をシンプルに保つ**：複雑さは脆弱性の温床。設計と実装を可能な限り単純にする。
- **5\. 既定で拒否する（Default deny）**：明示的に許可したものだけを通す。権限は拒否から始める。
- **6\. 最小権限の原則**：必要最小限の権限だけを与え、特権は必要な瞬間だけに限定する。
- **7\. 他システムへ渡すデータを無害化する**：DB・OSコマンド・外部APIへ渡す前にエスケープする（インジェクション対策の核）。
- **8\. 多層防御（Defense in depth）**：単一の防御に依存せず、入力検証・認可・暗号化を層状に重ねる。
- **9\. 品質保証を実践する**：ファジング・ペネトレーションテスト・ソースコード監査を使う。
- **10\. セキュアコーディング標準を採用する**：言語ごとの標準（CERT C/Java等）を定め、チームで統一運用する。

この10原則のうち、実際のWebアプリで事故に直結しやすいのは「1\. 入力検証」「5\. 既定で拒否」「7\. データの無害化」の3つだ。以降の脅威別対策も、突き詰めればこの3原則の各論になる。原則の並びに優劣は書かれていないため、順位はOWASPの統計で補う。どの取り組みから着手するかは、[OWASPの主要プロジェクトを俯瞰した記事](https://www.issoh.co.jp/tech/details/13128/)の守備範囲表から選ぶとよい。

## 主要な脆弱性とコードレベルの対策をOWASP Top 10 2025年版の順で見る

原則を具体的な攻撃に落とし込む。ここではOWASP Top 10 2025年版で上位に位置する脅威を、危険な実装と安全な実装のコードで対比する。2025年版は通算8回目の改訂で、サーバーサイドリクエストフォージェリ（SSRF）は独立カテゴリをやめてアクセス制御の不備へ統合された。

### アクセス制御の不備は既定で拒否しサーバ側で権限を判定して防ぐ

2025年版でも第1位（A01）は「アクセス制御の不備（Broken Access Control）」だ。40のCWEが束ねられ、平均3.73％のアプリケーションで該当する弱点が見つかっている。ログイン後の画面でも、URLのIDを書き換えれば他人のデータが見える、といった認可漏れが典型例になる。原則は「既定で拒否（原則5）」と「最小権限（原則6）」。権限判定を必ずサーバ側で行い（画面の出し分けだけで済ませない）、リソースごとに「この利用者がこの操作をしてよいか」を都度チェックする。パスワードのハッシュ化保存や多要素認証も併用する。

### SQLインジェクション対策は文字列連結をやめプレースホルダに統一する

SQLインジェクションは、ユーザー入力をそのままSQL文に連結した結果、入力に混ぜた文字列がSQLの一部として解釈される脆弱性である。認証回避やテーブル全体の窃取・破壊につながる。原因は原則7の違反＝入力を無害化せずDBへ渡していること。2025年版でインジェクションは3位から5位へ下がったが、紐づくCWEは38件、関連CVEの件数はカテゴリ中で最多だ。順位の低下は脅威の消滅ではなく、他カテゴリの押し上げによる。

```
# 危険：ユーザー入力を文字列連結でSQLに埋め込む
name = request.args["name"]
query = "SELECT * FROM users WHERE name = '" + name + "'"
cursor.execute(query)   # name に ' OR '1'='1 を入れると全件返る

# 安全：プレースホルダにバインドし、入力を値として扱う
cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
```

対策は、SQL文の骨格と値を分離するプレースホルダ（プリペアドステートメント）に統一すること。プレースホルダの記法はドライバで異なり、psycopg2やMySQLでは`%s`、標準ライブラリのsqlite3では`?`を使う。ORMを使う場合も、生SQLを組み立てる箇所だけは同じ注意が要る。攻撃の詳しい仕組みと攻撃例は[SQLインジェクションの仕組みと対策をコード付きで解説した記事](https://www.issoh.co.jp/column/details/3030/)で扱っている。

### XSS対策は出力時のエスケープとCSPヘッダで多層化して塞ぐ

XSSは、利用者の入力に含まれたスクリプトが、そのままHTMLとして出力されてブラウザで実行される脆弱性である。セッションクッキーの窃取や画面改ざんを招く。SQLインジェクションが「DBへ渡す入力」の問題なら、XSSは「HTMLとして出す出力」の問題という対比で覚えると混同しない。

```
# 危険：入力をそのままHTMLに埋め込む（Flask + Jinja2 で自動エスケープを外した例）
return render_template_string("<p>{{ comment | safe }}</p>", comment=comment)

# 安全：テンプレートの自動エスケープに任せる（|safe を付けない）
return render_template_string("<p>{{ comment }}</p>", comment=comment)
```

基本は「出力する文脈（HTML本文・属性値・JavaScript内・URL）に応じたエスケープ」を出力の瞬間に行うこと。多くのテンプレートエンジンは既定で自動エスケープするので、それを無効化しないのが第一歩になる。加えて`Content-Security-Policy`ヘッダでスクリプトの実行元を制限すれば、万一エスケープ漏れがあっても被害を抑えられる（原則8の多層防御）。XSSと混同されやすいCSRFとの違いや防止策は[XSSとCSRFの対策方法をまとめた記事](https://www.issoh.co.jp/tech/details/4109/)が詳しい。

### 機密データの保護は保存時と通信時の暗号化と鍵の分離で成立する

個人情報や認証情報は、保存時（データベース・ディスク）と通信時（ネットワーク）の両方で暗号化する。通信はTLSで保護し、保存データは用途に応じて暗号化やハッシュ化を使い分ける。暗号化の失敗（A04）は32のCWEを抱え、平均3.80％のアプリケーションで検出された。見落とされやすいのが鍵管理で、鍵をソースコードや設定ファイルに直書きすると暗号化の意味が失われる。鍵は専用のシークレット管理（環境変数・KMS等）へ置く。

### サプライチェーンの不備は依存関係の固定と取得元の検証で抑える

2025年版で新設されたA03「ソフトウェアサプライチェーンの不備」は、自作コードの外側――依存ライブラリ、ビルドシステム、配布インフラ――で起きる侵害をまとめたカテゴリだ。紐づくCWEは5件、検出データ上の出現も最少だが、関連CVEの平均的な悪用容易性と影響度はカテゴリ中で最も高い。テストが追いついていないだけで、当たれば被害が大きい領域という位置づけになる。

```
# 危険：バージョンも取得元も固定せずインストールする
pip install requests

# 安全：ハッシュ付きでロックした要件ファイルから入れる
pip install --require-hashes -r requirements.lock
```

実装側の打ち手は地味だ。依存をロックファイルで固定し、ハッシュ検証を有効にし、ビルドに使う認証情報の権限を絞る。既知脆弱性との照合を自動化する手段は[OSV-ScannerとTrivyの違いを整理した記事](https://www.issoh.co.jp/tech/details/12926/)で比較している。

### 例外処理の不備はfail closedの原則とエラー出力の分離で塞ぐ

もう一つの新設カテゴリがA10「例外処理の不備」で、24のCWEが該当する。誤ったエラー処理、論理エラー、異常時に許可側へ倒れる実装などが対象だ。判定に失敗したときに通してしまう「fail open」は、原則5「既定で拒否」の真逆にあたる。

```
# 危険：例外を握りつぶして処理を続行する（fail open）
try:
    allowed = check_permission(user, resource)
except Exception:
    allowed = True          # 判定に失敗したのに通してしまう

# 安全：判定できないときは拒否側へ倒す（fail closed）
try:
    allowed = check_permission(user, resource)
except Exception:
    logger.exception("authz check failed")
    allowed = False
```

あわせて、例外の中身を画面へそのまま返さないこと。スタックトレースやSQL文が応答に出れば、それ自体が攻撃者への情報提供になる。利用者には一般化したメッセージを返し、詳細はサーバ側のログにだけ残す。ログへ外部入力を書くときは改行コードを除去する（ログインジェクション対策）。

## 参照すべきガイドラインと標準を国内外の一次情報から使い分ける手順

セキュアコーディングは自己流で組み立てるより、公開された標準に沿うほうが抜け漏れが少ない。ただし資料には鮮度の差があり、国内の日本語資料はそのまま最新版として扱えないものがある。

| 提供元       | 資料             | 版・時点           | 使いどころ         |
| --------- | -------------- | -------------- | ------------- |
| OWASP     | Top 10         | 2025年版（通算8回目）  | Webリスクの優先順位付け |
| MITRE     | CWE Top 25     | 2025年版         | 弱点の分類と共通言語    |
| IPA       | 安全なウェブサイトの作り方  | 改訂第7版          | 国内Web実装の具体手順  |
| IPA       | セキュア・プログラミング講座 | 2016年10月版・保管扱い | 原則の背景を理解する    |
| JPCERT/CC | CERT C／Javaの規約 | 2013年6月が最終更新   | C・C++・Javaの規約 |
| SEI CERT  | セキュアコーディング10原則 | 言語非依存          | 原則の起点にする      |

OWASP Top 10は2025年版で改訂され、セキュリティ設定の不備が2021年版の5位から2位へ繰り上がり、サプライチェーンの不備（A03）と例外処理の不備（A10）が新設された。ログ関連のカテゴリ名も「監視」から「警告」へ変わっている。変更点の全体像は[OWASP Top 10 2025年版の変更点をまとめた記事](https://www.issoh.co.jp/tech/details/9917/)で確認できる。CWE Top 25は2025年版が現行で、母集団は39,080件のCVEレコード。上位25件に加え、「あと一歩で圏内だった」15件とKEV（悪用が確認された脆弱性）向けの上位10件が併載されている。

鮮度の差は国内資料に出る。IPA「セキュア・プログラミング講座」は2016年10月版（2017年6月一部修正）を最後にアーカイブへ移された。Web実装の手順を日本語で追うなら「安全なウェブサイトの作り方」改訂第7版（第1章で11種類の脆弱性を扱う）のほうが実務に近い。JPCERT/CCのセキュアコーディングのページはC/C++とJavaの規約が中心で、2026年9月時点の最終更新は2013年6月27日だった。

使う順番はこうなる。まずOWASP Top 10で「何が起きやすいか」を掴み、CWEで「原因の型」を特定し、IPAの「安全なウェブサイトの作り方」やCERTの言語別標準で「どう書くか」を決める。古い日本語資料は原則の理解に使い、版番号や順位の根拠には使わない。

## 言語別に押さえる注意点と事故が起きやすい実装箇所の違いを整理する

原則は共通でも、事故が起きやすい箇所は言語ごとに異なる。主要言語の代表的な注意点を挙げる。

- **C / C++**：バッファオーバーフローとメモリ破壊が最大のリスク。`gets`など危険な関数を避け、境界チェックのある関数を使う。CERT C標準が具体的な規約を示す。
- **Java**：デシリアライズの脆弱性やSQLインジェクションに注意。`PreparedStatement`でクエリを組み立て、信頼できないデータのデシリアライズを避ける。
- **Python**：`eval`や`pickle`への信頼できない入力の流し込み、コマンド実行での`shell=True`が定番の穴。パラメータ化されたAPIを使い、依存ライブラリの脆弱性も`pip-audit`等で監視する。
- **JavaScript / Node.js**：DOMベースXSSや`npm`依存パッケージの脆弱性が中心。`innerHTML`への直接代入を避け、依存関係を`npm audit`で継続チェックする。
- **PHP**：ファイルアップロードの検証漏れと、`include`系でのパス操作が事故になりやすい。拡張子ではなく内容と保存先で制御し、公開ディレクトリに実行可能ファイルを置かない。

## セキュアコーディングを支えるツールとCI/CDへの組み込み手順

人のレビューには意味があるが、それだけでは見落としが残る。自動検出をCI/CDに組み込み、コードが増えるたび機械的にチェックする仕組みが要る。

- **SAST（静的アプリケーションセキュリティテスト）**：ソースコードを実行せずに脆弱性パターンを検出する。仕組みは[静的解析の解説記事](https://www.issoh.co.jp/tech/details/7475/)が詳しく、代表的なツールに[SonarQube](https://www.issoh.co.jp/column/details/2988/)がある。
- **DAST（動的アプリケーションセキュリティテスト）**：稼働中のアプリに実際にリクエストを送って脆弱性を探る。無償の定番が[OWASP ZAP](https://www.issoh.co.jp/tech/details/2958/)で、検出できる項目の一覧が参考になる。
- **依存ライブラリ検査（SCA）**：自作コードより、使っているライブラリの既知脆弱性のほうが事故の入口になりやすい。`npm audit`・`pip-audit`やDependabot等で継続監視する。A03の新設はこの層の比重が上がったことを示している。
- **コンテナイメージの検査**：アプリ本体が無傷でも、ベースイメージのパッケージが穴になる。組み込み方は[Dockerの脆弱性診断をCI/CDへ組み込む手順の記事](https://www.issoh.co.jp/tech/details/3795/)にまとめた。

ツールは「導入して終わり」ではなく、検出結果を修正まで回すフローとして運用することが前提になる。

## 既存プロジェクトへ後から導入する5工程と着手順の決め方の指針

新規開発ならルールを最初から敷けるが、稼働中のシステムに後から入れる場合は順番を誤ると止まる。着手順は次の5工程で決める。

1. **棚卸し**：外部から届く入力の口（画面・API・ファイル取り込み・Webhook）を一覧化し、認証の有無と権限判定の場所を書き出す。
2. **優先度付け**：OWASP Top 10 2025年版の順位と自社での影響度を掛け合わせて対象を絞る。全項目を同時に潰そうとしない。
3. **コーディング標準の明文化**：言語ごとに「やらないこと」を10行程度で定め、レビュー観点に落とす。長い規約は読まれない。
4. **自動検出の接続**：SASTとSCAをプルリクエスト単位で回す。既存の検出はベースラインとして受け入れ、新規混入だけを失敗条件にする。
5. **残存リスクの確認**：ツールで拾えない認可漏れや設計起因の問題を、外部の診断で確認する。

工程3を飛ばして工程4から始める現場が多い。それだと検出結果の採否を誰も判断できず、警告が積み上がったまま放置される。明文化は短くてよいので先に置く。

## AIが生成したコードのレビューで追加して見る観点と現状の限界

コード生成アシスタントを前提にした開発では、レビューの負荷が「書く」から「確かめる」へ移る。生成コードは動作確認が通っていても次の3点を人が見る。

- **存在しない依存の混入**：インポート先が実在するか、名前が似ているだけの別パッケージでないかを確認する。A03の観点そのものになる。
- **認可判定の位置**：生成コードは機能を満たす実装を優先するため、権限チェックが画面側だけに置かれることがある。サーバ側の判定が入っているかを見る。
- **例外処理の倒れ方**：`except`で握りつぶして既定値を返す実装が混ざりやすい。A10の観点で、拒否側に倒れるかを確認する。

生成AIを組み込んだアプリケーションでは、脅威の種類そのものが変わる。プロンプトインジェクションや学習データの汚染は既存のTop 10では捉えきれず、[OWASP Top 10 for LLMを整理した記事](https://www.issoh.co.jp/tech/details/12798/)の項目を別立てで見る必要がある。逆に、LLMを使っていない一般的なWebアプリには従来のTop 10の観点で足りる。生成AIを理由に点検項目を増やす前に、どちらの話をしているのかを切り分けたい。

## セキュアコーディングが形骸化する典型パターンと避けるべき進め方

ガイドラインを配っても事故が減らない現場には共通の失敗がある。避けるべきパターンを挙げておく。

- **チェックをクライアント側だけで済ませる**：JavaScriptの入力チェックは利用体験には役立つが、攻撃者はブラウザを介さず直接リクエストを送れる。これをセキュリティ対策とみなすのは危険だ。
- **コンパイラ／リンタの警告を放置する**：警告は将来の脆弱性の予告であることが多い。「動くから」と警告を抱えたまま進めると、原則2が空文化する。
- **ツール導入を目的化する**：SASTを入れても、検出結果を誰も修正しなければコストが増えるだけ。検出→トリアージ→修正までを回して初めて意味を持つ。
- **古い資料を最新として配る**：更新の止まった日本語資料をそのまま新人教育に使うと、サプライチェーンや例外処理といった新しい論点が丸ごと抜ける。

## SASTを内製で回すか脆弱性診断を外部に出すかを分ける判断条件

どこまで自社で見て、どこから外へ出すか。判断は網羅性ではなく「検出手段の性質」で切る。

SASTとSCAは内製で回すべきだ。プルリクエストごとに自動で走らせる性質のもので、外部に都度依頼すると開発速度と噛み合わない。一方、認可漏れ・業務ロジックの抜け・複数機能をまたぐ攻撃経路は、ツールがほぼ拾えない。ここが第三者の手を入れる領域になる。分岐点は、扱うデータが個人情報や決済情報を含むか、障害時に外部への説明責任が生じるかの2つ。どちらかに該当するなら、リリース前に外部診断を挟む前提で計画を組む。

外部に出す場合も、丸投げでは報告書を消化できない。対象範囲の決め方・検出結果のトリアージ・再診断のタイミングは[脆弱性診断のやり方を5工程で整理した記事](/column/details/13101/)にまとめている。切り分けが難しい場合や、開発と診断を一本の流れにしたい場合は、[脆弱性診断・セキュリティ診断のサービス](https://www.issoh.co.jp/service/system/vulnerability/)から相談してもらえれば、範囲の設計から実施・再診断まで引き受けられる。

逆に、社内利用のみで個人情報を扱わない小規模な管理ツールへ、リリースのたび外部診断を掛けるのは過剰だ。そこはSAST・SCAの自動検出と、認可まわりのチェックリストで足りる。

## よくある質問

セキュアコーディングとは何かを調べる過程でよく挙がる質問を、5つに絞って答える。

### セキュアコーディングとセキュアプログラミングは違いますか？

ほぼ同義です。どちらも脆弱性を作り込まないコーディング手法を指し、IPAの資料でも「セキュア・プログラミング」という呼称が使われています。本記事では区別せず扱います。

### 「セキュア」とはどういう意味ですか？

情報セキュリティの文脈では、システムやデータが不正アクセス・改ざん・漏えいから守られている状態を指します。具体的には機密性・完全性・可用性の3要素が保たれていることを意味し、セキュアコーディングはこれをコードのレベルで実現する営みです。

### セキュアコーディングの原則はいくつありますか？

広く参照されるのはSEI CERTの「Top 10 Secure Coding Practices」で、入力検証・コンパイラ警告の解消・既定で拒否・最小権限・多層防御など10項目です。国内記事の「10個の原則」もこれを基にしていることが多いです。

### どのプログラミング言語から学ぶべきですか？

原則は言語共通なので、まず自分が実装に使う言語の注意点から押さえるのが実務的です。Webアプリ中心ならSQLインジェクションとXSSの対策、C/C++を扱うならメモリ安全性、というように、担当領域で事故が起きやすい箇所を優先します。

### まず参照すべき公式ガイドラインはどれですか？

優先順位付けにはOWASP Top 10の2025年版、実装手順にはIPA「安全なウェブサイトの作り方」改訂第7版が出発点になります。原因の分類はMITREのCWE Top 25（2025年版）が共通言語として役立ちます。国内の古い講座資料は原則の理解にとどめ、順位や版番号の根拠には使わないでください。

## 関連記事

- [SQLインジェクションとは？仕組み・攻撃例・対策をコード付きで解説](https://www.issoh.co.jp/column/details/3030/)：本記事のA05の各論にあたる
- [XSSとCSRFの違いとは？仕組み・被害・対策を実装レベルで徹底比較](https://www.issoh.co.jp/tech/details/4109/)：出力側の対策を詳しく扱う
- [OWASP Top 10 2025年版とは？正式版の10項目と2021年版からの変更点](https://www.issoh.co.jp/tech/details/9917/)：優先順位の根拠となる一次情報の解説
- [DevSecOpsとは？DevOpsとの違い・ライフサイクル・導入判断を実装視点で解説](/tech/details/13538/)：コーディングの外側、プロセス全体の設計
- [脆弱性診断のやり方｜5工程の手順とトリアージ・再診断の判断基準](/column/details/13101/)：外部診断へ出すときの進め方

---

出典: [セキュアコーディングとは？10原則と主要脆弱性のコード対策を実装目線で解説](<https://www.issoh.co.jp/column/details/2373/>)（株式会社一創）
