09. セキュアプログラミングと開発プロセス

【情報処理安全確保支援士試験対策】手戻りゼロの堅牢なコードを!セキュア開発と脆弱性対策の総復習

2026年2月7日

1999年にインフラエンジニアとしてキャリアをスタートした当時、「セキュリティはファイアウォールで守るもの」というのが現場の常識でした。CodeRedやSQL Slammerが猛威を振るった時代でさえ、脆弱なコードがそのままリリースされ、境界防御で食い止めるのが当たり前でした。

2005年にCIOとなりましたが、最大の苦労は技術ではなく「セキュリティ予算を経営陣から引き出すこと」でした。ちょうど個人情報保護法が全面施行された年にもかかわらず、目に見えない対策への投資は後回しにされがちで。今振り返れば、ヒヤリハットの連続だったと思います。「何も起きなかった」のは、運が良かっただけかもしれない。そんな認識が、私の中でのシフトレフトの原点です。

2016年から新卒エンジニアへ教える立場になると、DevSecOpsの浸透とともに景色は大きく変わりました。そして2021年12月のLog4Shellが、「自社のコードだけ守ればいい」という最後の幻想を打ち砕きました。

本記事では、この20年余りの経験を踏まえ、セキュアプログラミングと開発プロセスを体系的に整理します。「なぜその対策が必要か」「攻撃者はどこを突くか」という視点で読み進めることで、科目B(旧午後)の記述問題にも通用する応用力が身につきます。

入力と出力の境界防御:すべてのデータは「毒」と思え

セキュアプログラミングの基本にして奥義、それは「入力値検証(バリデーション)」と「出力対策(サニタイズ/エスケープ)」です。Webアプリケーションに限らず、あらゆるシステムにおいて、外部から受け取るデータはすべて「信頼できないもの」として扱う必要があります。

入力値検証の「ホワイトリスト」と「ブラックリスト」

入力値検証において、試験でも実務でも基本となる考え方が「ホワイトリスト方式」の採用です。

ホワイトリスト方式(許可リスト)

「許可する文字種、長さ、形式」を定義し、それに合致するものだけを通す方法です。例えば、郵便番号フィールドなら「数字のみ」「7桁」以外はすべて拒否します。未知の攻撃パターンや想定外の特殊文字が含まれていても、定義外であれば弾くことができるため、安全性が高いというメリットがあります。

ブラックリスト方式(拒否リスト)の問題点

「危険な文字(<、>、'、"など)」を定義し、それを含むものを拒否または削除する方法です。しかし、攻撃手法は日々進化しており、すべての危険なパターンを網羅することは不可能です。また、文字コードの解釈の違いなどを利用した回避策(WAFバイパスなど)が存在するため、防御として不完全になりがちです。

情報処理安全確保支援士試験の科目Bで「セキュリティ対策として不適切な点はどこか」と問われた際、「ブラックリスト方式で特定のタグのみを削除している」といった記述があれば、それは指摘すべきポイントとなります。

ホワイトリストによる入力値検証と、出力箇所に応じたエスケープ処理のデータフロー図

出力対策:コンテキスト(文脈)を読む力

入力時に厳格なチェックを行っても、データベースに保存されたデータや、そのままブラウザに表示するデータが安全とは限りません。ここで重要になるのが「出力時のエスケープ処理」です。重要なのは、「データを出力する場所(コンテキスト)によって、無害化の方法が異なる」という点です。

HTML本文に出力する場合

<を&lt;に、>を&gt;に変換するなど、HTML特殊文字をエスケープします。これにより、スクリプトタグとして解釈されることを防ぎます(XSS対策)。

JavaScript内に出力する場合

インラインスクリプトに埋め込む場合は、JavaScript文字列とHTMLのscript要素の両方を考慮したエスケープ(\uXXXX 形式など)が必要です。文字列中に </script> が含まれると、HTMLパーサーがscript要素の終了タグと解釈してしまうためです。データはJSONとして別リクエストで受け渡す(Content-Type: application/json)方法も有効ですが、JSON化しただけで安全になるわけではありません。HTMLエスケープだけでは不十分なケースがあります。

SQLクエリに埋め込む場合

プレースホルダ(バインド機構)を使用します。SQL文の構造を先に確定させ、入力値は後から「データ」として割り当てるため、入力値がSQL文の一部として解釈されることがなく、SQLインジェクションを根本的に防げます。なお、IPAはライブラリ側でエスケープ処理を行う「動的プレースホルダ」よりも、データベース側でSQL文を確定させる「静的プレースホルダ」の利用を推奨しています。

「サニタイズしていればOK」という短絡的な思考ではなく、「どこの文脈に出すから、どういう処理が必要か」を論理的に説明できるようにしておきましょう。

”
FREE PDF
SC午後記述
テンプレート集
登録特典
メール講座 登録で無料プレゼント
「知っているのに書けない」を、型で解消するPDF
設問の文末から解答の「型」を割り出し、そのまま当てはめて書く。SC午後の記述で手が止まらなくなる1冊です。
設問6タイプ分類頻出7テーマ減点10パターン時間配分&見直し
無料でPDFを受け取る →

+おまけ:毎日1通の無料メール講座つき。登録した日が「1日目」、図解と論理で16週間かけて基礎も固まります。

登録無料·いつでも配信停止

開発プロセスそのものを守る:DevSecOpsとサプライチェーン

コードを書く人間が気をつけるだけでは限界があります。開発のライフサイクル全体にセキュリティを組み込む「DevSecOps」と、利用する部品の安全性を担保する「サプライチェーンセキュリティ」は、近年の最重要トピックです。

セキュリティバイデザインと手戻りのコスト

「セキュリティバイデザイン」とは、企画・設計段階からセキュリティ対策を組み込む考え方です。もし、出荷直前のテストフェーズで致命的な脆弱性(例:アーキテクチャレベルでの認証不備)が見つかった場合、その修正コストは設計段階で修正する場合の何倍にも膨らみ、リリース後に見つかればさらに大きくなると言われています。

これを防ぐための具体的なアクションが「脅威モデリング」です。

  • システムに対する脅威を洗い出す(STRIDEモデルなどが有名)
  • 攻撃者の視点でデータフロー図(DFD)を分析する
  • 「ここで認証を突破されたらどうなるか?」「この通信路は暗号化されているか?」を机上でシミュレーションする

試験では、要件定義や設計段階のレビューで何をチェックすべきか、という観点で問われることがあります。

DevOpsの無限ループの各工程にセキュリティ対策(脅威分析、SAST、DASTなど)が統合されたDevSecOpsの概念図

見えない時限爆弾:OSSとサプライチェーン攻撃

現代の開発において、OSS(オープンソースソフトウェア)やライブラリを利用しないプロジェクトはほぼ存在しません。しかし、それは「他人が書いたコード」を自社のシステム内で、自社のコードと同じ権限で動かすことを意味します。

依存関係の深淵

自社で導入したライブラリAが、内部でライブラリBを使用し、さらにそれがライブラリCを使用している…という「依存関係の連鎖」があります。Log4jの脆弱性(Log4Shell)が世界を震撼させたのは、あまりに多くのJava製品が深層でこのライブラリに依存していたためです。

SBOM(Software Bill of Materials)の重要性

これに対抗する手段として、ソフトウェア部品表(SBOM)の整備が急務となっています。SBOMは、システムに含まれるすべてのコンポーネント、バージョン、ライセンス情報のリストです。脆弱性が公開された際、正確かつ最新のSBOMを脆弱性情報や配備先情報と照合することで、「自社製品のどこに、該当するバージョンのライブラリが使われているか」の特定を迅速化でき、パッチ適用や回避策の実施判断につなげられます。

試験対策としては、「JVNなどで脆弱性情報を収集する」だけでなく、「自社の資産構成(インベントリ)を正確に把握しておくこと」がセットで必要であると理解してください。

管理されていない依存関係は構成も脆弱性も把握できない一方、SBOMで部品とバージョンを一覧化し、脆弱性情報と照合することで対応が必要な部品(Log4j 2.14.1など)を特定できることを示す比較図

脆弱性をあぶり出す技術:SAST・DAST・ファジング

人間によるコードレビューには限界があります。ツールを活用した自動化テストは、開発効率とセキュリティ品質を両立させる鍵です。それぞれのツールの特性と使い分けを整理しましょう。

静的解析(SAST)と動的解析(DAST)の使い分け

この2つは競合するものではなく、補完し合う関係です。

SAST(Static Application Security Testing)

  • タイミング: コーディング中、またはビルド時。ソースコードそのものを解析します
  • 得意分野: コーディング規約違反、既知の危険な関数(strcpyなど)の使用、SQLインジェクションやXSSにつながるコードパターンの発見
  • 弱点: 実際に動かさないと分からない論理的なバグや、設定ファイルとの組み合わせによる不具合は検出しにくい。誤検知(False Positive)も多い

DAST(Dynamic Application Security Testing)

  • タイミング: テスト環境やステージング環境でアプリケーションが稼働している状態
  • 得意分野: 実際のHTTPリクエストを送信し、レスポンスを解析する。認証・認可の不備、セッション管理の不備、サーバーの設定ミス(ヘッダ不備など)を発見できる(ただしBOLAのような複雑な認可不備は、複数ユーザーで試すシナリオ設計や手動診断で補う必要がある)
  • 弱点: コードのどの行に問題があるかまでは特定できない場合がある。テストの実行に時間がかかる

未知のバグを叩き出す「ファジング」

ファジング(Fuzzing)は、予測不可能なデータを大量にテスト対象のプログラムに送り込み、クラッシュや予期せぬ挙動(例外発生、メモリリークなど)を引き起こさせるテスト手法です。

特に、IoT機器のファームウェアや、独自プロトコルのサーバー、ファイルパーサーなどの検証で威力を発揮します。開発者が想定する「境界値」だけでなく、極端に長い文字列、不正なバイナリデータ、空データなどを機械的に生成して送り続けることで、人間では思いつかないようなバグ(ゼロデイ脆弱性の種)を発見することができます。

試験では、午前Ⅱ(現・科目A-2)で問題を引き起こす可能性があるデータを大量に入力し、その応答や挙動を監視することで脆弱性を検出するテスト手法としてファジングを選ばせる問題が出題されています(平成31年春期 午前Ⅱ 問22)。通常のテスト仕様書に基づくテストでは見つけられないバグを見つけるための手法であることを押さえておきましょう。

メモリ管理とAPI:言語とアーキテクチャ特有の課題

プログラミング言語やアーキテクチャによって、警戒すべき脆弱性の種類は変わります。

C/C++におけるメモリ破壊の恐怖

C言語やC++のように、開発者がメモリ管理を直接行う言語では、「バッファオーバーフロー」が依然として重大な脅威です。

スタックバッファオーバーフローの仕組み

ローカル変数が格納される「スタック領域」において、確保されたバッファサイズを超えるデータを書き込むことで、隣接するメモリ領域を破壊します。典型的な攻撃では、攻撃者はこれにより関数の「リターンアドレス」を書き換え、攻撃コード(シェルコード)が配置されたメモリアドレスへ実行フローをジャンプさせます。

対策の実装

言語レベルでは、strcpyのような境界を検査しない関数を避け、コピー先のサイズを指定できる関数(strncpy、snprintfなど)を使用してバウンダリチェック(境界検査)を行います。ただしstrncpyは、コピー元が長い場合にコピー先が終端のNUL文字で終わらないことがあるため、終端処理もあわせて必要です。OS/コンパイラレベルでは、ASLR(アドレス空間配置のランダム化)やDEP(データ実行防止)、スタックカナリア(Stack Canary)の導入が有効です。

試験では、メモリのスタック構造図を見て、どこが書き換わると制御が奪われるかを問う問題が出ることがあります。「リターンアドレスの書き換え」がキーワードです。

スタック上でバッファの境界を超えて書き込まれたデータが、保存されたフレームポインタとリターンアドレスを上書きし、リターンアドレスが攻撃コードのアドレスに書き換えられるスタックバッファオーバーフローの仕組み図

APIエコノミー時代の落とし穴

Web API(特にREST API)が標準となった現代において、API固有の脆弱性も狙われています。

BOLA(Broken Object Level Authorization)

日本語では「オブジェクトレベルの認可不備」。例えばGET /api/users/123/infoというリクエストで自分の情報が見られる時、IDを124に書き換えて他人の情報が見えてしまう脆弱性です。認証(ログインしているか)はチェックしていても、認可(そのリソースにアクセスする権限があるか)のチェックが漏れているケースが非常に多いです。

JWT(JSON Web Token)の不適切な利用

認証トークンとしてJWTが普及していますが、実装ミスが散見されます。

  • 署名アルゴリズムをnoneに設定して署名チェックを回避する攻撃
  • HS256などのHMAC署名で使う共有鍵(シークレット)が推測可能な弱い文字列になっている
  • トークンの有効期限検証を行っていない

APIセキュリティにおいては、「サーバー側で必ず状態と権限を再検証する」というゼロトラストの原則が適用されているかどうかが問われます。

セキュア開発における「組織」と「人」の役割

技術的な対策だけでは、セキュリティは完結しません。最終的には「人」と「ルール」が重要になります。

誤解されがちな「WAFがあれば大丈夫」

「脆弱性を作り込んでしまっても、WAF(Web Application Firewall)を入れれば防げる」という考え方は危険です。WAFはあくまで「応急処置」や「保険」であり、根本的な解決策ではありません。WAFのシグネチャ(検知ルール)をすり抜ける攻撃は常に存在しますし、アプリケーションのロジックに起因する脆弱性(例:ビジネスロジックの悪用や権限昇格)は、WAFでは検知できないことが多いです。

情報処理安全確保支援士試験の記述問題で、対策案として「WAFの導入」を書く場合、それが「根本対策までのつなぎ」なのか、「多層防御の一環」なのかを明確にする必要があります。「ソースコードの修正」が最も根本的な対策であることを忘れてはいけません。

教育と啓発:開発者のスキルアップ

セキュアなコードを書くためには、開発者自身が攻撃手法を知っている必要があります。「SQLインジェクションとは何か」を知らない開発者に、プレースホルダの使用を強制しても、なぜそれが必要なのか理解できず、抜け穴のある実装をしてしまう可能性があります。

組織的な対策として、以下の取り組みが有効です。

  • セキュアコーディングガイドラインの策定と周知: 言語やフレームワークに合わせた具体的なルールブックを作る
  • 定期的なセキュリティトレーニング: 座学だけでなく、実際に脆弱なアプリを攻撃してみるハンズオン形式(CTFなど)が効果的
  • セキュリティチャンピオン制度: 各開発チームの中からセキュリティの推進役(チャンピオン)となるメンバーを任命し、現場レベルでの相談役とする

実務で陥りやすいセキュリティの落とし穴

試験対策だけでなく、実務での注意点も押さえておきましょう。知識があっても、実装時のちょっとした油断が重大な脆弱性につながることがあります。

「後で対応する」の危険性

開発現場でよく聞かれる「とりあえず動くものを作って、セキュリティ対策は後で実装する」という考え方は非常に危険です。後回しにされたセキュリティ対策は、スケジュールの圧迫により最終的に実装されないケースが多く見られます。また、後からセキュリティ機能を追加しようとすると、既存のアーキテクチャと整合性が取れず、継ぎはぎの対策になってしまうリスクがあります。

テスト環境と本番環境の設定差異

テスト環境では問題なく動作していたのに、本番環境でセキュリティインシデントが発生するケースがあります。これは、環境間の設定差異が原因であることが多いです。

  • デバッグモードが本番環境でも有効になっている
  • テスト用の認証情報やAPIキーがハードコードされている
  • エラーメッセージの詳細表示が本番環境でも有効

環境間の設定を一元管理し、本番環境固有のセキュリティ設定が確実に適用されるようにしましょう。Infrastructure as Code(IaC)を活用することで、設定の一貫性を保つことができます。

サードパーティライブラリの無計画な導入

便利なライブラリを見つけると、すぐに導入したくなるものです。しかし、以下の点を確認せずに導入すると、後々問題になります。

  • ライブラリのメンテナンス状況(最終更新日、コミュニティの活発さ)
  • 既知の脆弱性の有無(CVEデータベースでの確認)
  • ライセンス条件(商用利用の可否、ソースコード開示義務の有無)
  • 依存関係の深さ(さらにどのようなライブラリに依存しているか)

特に、メンテナンスが停止しているライブラリは、脆弱性が発見されても修正されない可能性が高いため、代替ライブラリへの移行を検討すべきです。

セキュリティ品質を高める継続的改善

セキュリティは一度対策すれば終わりではありません。新しい攻撃手法の出現、システムの機能追加、法規制の変更など、様々な要因により継続的な見直しが必要です。

セキュリティメトリクスの活用

セキュリティ対策の効果を測定し、改善につなげるためには、適切な指標(メトリクス)の設定が重要です。

プロセスメトリクス

  • コードレビューでの脆弱性検出数
  • 静的解析ツールでの検出項目数と修正率
  • セキュリティ教育の受講率

成果メトリクス

  • 本番環境での脆弱性検出数(ペネトレーションテストなど)
  • インシデント発生件数と平均解決時間
  • 脆弱性の再発率

これらの指標を定期的にモニタリングし、傾向分析を行うことで、組織のセキュリティ成熟度を可視化できます。

インシデントからの学び

セキュリティインシデントが発生した場合、それを組織の学習機会として活用することが重要です。

  • 根本原因分析(Root Cause Analysis)の実施
  • 再発防止策の立案と実施
  • インシデント事例の社内共有(個人の責任追及ではなく、組織の改善として)
  • 開発プロセスやチェックリストへの反映

「誰が悪かったか」ではなく「なぜ防げなかったか」「どうすれば防げるか」という建設的な議論を行うことで、組織全体のセキュリティレベルが向上します。

試験に向けたマインドセットの再確認

セキュア開発に関する知識は、情報処理安全確保支援士試験の科目Bにおいて、長文の事例問題の中で「プログラミングコードの断片」や「設計レビューの会話」として現れます。

合格に必要な3つの視点

試験合格には、以下の3つの視点を瞬時に切り替える能力が求められます。

プログラマの視点

「このコードの、この変数の扱いは危ない」と具体的な行数を指摘できるか。

アーキテクトの視点

「このシステム構成なら、ここで認証を挟まないとバックエンドが守れない」と構造上の欠陥を見抜けるか。

マネージャーの視点

「開発プロセスに静的解析ツールを導入し、リリース判定基準にセキュリティ項目を追加する」という組織的な改善案を提示できるか。

これらを意識しながら、過去問演習に取り組むことで、解答の精度を高められます。

科目Bで問われる実践的な知識

科目Bでは、単なる用語の知識ではなく、実際のシステム開発における判断力が問われます。以下のような問題に対応できる力を養いましょう。

  • コードレビューで指摘すべき脆弱性の特定
  • 設計段階で考慮すべきセキュリティ要件の抽出
  • インシデント発生時の原因分析と再発防止策の立案
  • セキュリティツールの適切な選定と導入タイミングの判断

過去問を解く際は、解答を覚えるのではなく、「なぜその対策が必要なのか」「他の選択肢はなぜ不適切なのか」を論理的に説明できるようにすることが重要です。

手戻りゼロのコードを目指して。セキュアプログラミング理解度チェック

「セキュリティは完成してから考える」という考えは、現代の開発現場では致命的なリスクとなります。脆弱性をリリース直前に発見して手戻りが発生するのを防ぐには、設計・実装段階での正しい知識が不可欠です。 この練習問題では、SQLインジェクションやXSSなどの古典的な脅威から、近年のトレンドであるOSS管理(SBOM)やAPIセキュリティまでを網羅しています。攻撃者の視点を持ち、堅牢なアプリケーションを構築するための判断力を磨いてください。

【演習】セキュア開発と脆弱性対策 総復習(全10問)

今週のまとめ:品質としてのセキュリティ

今週は、開発フェーズに焦点を当てて復習を行いました。ポイントを振り返ります。

入力値検証と出力エスケープ

基本中の基本。ホワイトリストで守り、コンテキストに合わせてエスケープする(入力値検証とエスケープの解説)。

DevSecOps

開発スピードを落とさず、SAST・DASTによる検査をパイプラインに組み込み、検出結果の確認・修正・再検証を継続的に行う(セキュリティバイデザインとDevSecOpsの解説、SAST・DAST・ファジングの比較)。

サプライチェーン管理

自社のコードだけでなく、OSS(ライブラリ)の脆弱性もSBOM等で管理する(サプライチェーン攻撃とSBOMの解説)。

言語・環境別の特性

C/C++のメモリ管理、APIの認可制御など、環境に応じた急所を押さえる(Java・C/C++の脆弱性パターン、REST APIセキュリティの解説)。

セキュリティは、機能要件(何ができるか)と同等以上に、非機能要件(品質)として重要です。複雑なソフトウェアについて、バグや脆弱性が存在しないと保証することは困難です。それでも、継続的な対策でリスクを低減していく努力とプロセスが、情報処理安全確保支援士には求められています。

次のステップとして、視点を「クラウド環境」と「最新技術」に移していきましょう。AWSやAzureなどのクラウド利用時の責任共有モデル、コンテナ技術(Docker/Kubernetes)のセキュリティ、そしてゼロトラストネットワークといったモダンなトピックへと学習を進めます(総まとめは「クラウド・コンテナ・ゼロトラスト完全ガイド」)。

基礎となるネットワークや攻撃手法、そして今回の開発プロセスの知識が、クラウドセキュリティの理解を深める土台となります。週末は、苦手な言語の脆弱性パターンを見直し(XSSなどの入力値検証・エスケープは解説記事も参照)、コードレベルでの「違和感」に気づけるよう目を養っておきましょう。

合格への道は、確実な知識の積み上げの中にあります。継続的な学習を進めていきましょう。

”
FREE PDF
SC午後記述
テンプレート集
登録特典
メール講座 登録で無料プレゼント
「知っているのに書けない」を、型で解消するPDF
設問の文末から解答の「型」を割り出し、そのまま当てはめて書く。SC午後の記述で手が止まらなくなる1冊です。
設問6タイプ分類頻出7テーマ減点10パターン時間配分&見直し
無料でPDFを受け取る →

+おまけ:毎日1通の無料メール講座つき。登録した日が「1日目」、図解と論理で16週間かけて基礎も固まります。

登録無料·いつでも配信停止
自社のセキュリティ対策に不安はありませんか?
BKサクセスでは、専任の情シスがいない中小企業様向けに、伴走型のセキュリティ対策支援を行っています。
まずは無料相談から、お気軽にご連絡ください。
✉️ セキュリティ対策について相談する(無料)

▼ 本気で難関資格を狙うなら、攻略法から

資格スクエア

▼ 理想の転職へ。まずはプロに相談

  • この記事を書いた人

Kenta Banno

元CIOの窓際サラリーマン(50代)。プライム上場企業の片隅で、情報処理安全確保支援士の合格を目指して奮闘中! 現在はAI(Gemini/Claude)を「壁打ち相手」として徹底活用し、日々の学習の備忘録とアウトプットを兼ねて記事を投稿しています。同じ資格を目指す初学者の参考になれば嬉しいです。

-09. セキュアプログラミングと開発プロセス