【特集】セキュア・ソフトウェア開発ガイド セキュリティ

セキュリティプログラミング

投稿日:

セキュリティプログラミングとは、ソフトウェア開発において、脆弱性を作り込まないように安全な実装を行うことを意味します。目的は、外部からの攻撃や内部不正による情報漏えい、改ざん、サービス停止を防ぐことです。

■ セキュアコーディングの基準

セキュアコーディングのための主なポイントは以下の通りです。

 ・入力値の検証(バリデーション)
 ・バッファオーバーフロー対策
 ・エラーメッセージに機密情報を含めない
 ・安全な乱数生成(rand()ではなく暗号論的乱数)

これらを規定した代表的なガイドラインには以下があります。

基準 特徴主な適用分野
OWASP Secure Coding PracticesWebアプリ開発での安全な実装指針Webアプリケーション
Web API
CERT Secure Coding Standard言語別の詳細な安全実装ルールC/C++、Javaなどの組込みや業務アプリ
MISRA C / MISRA C++安全性重視の組込みシステム向けルール自動車・産業機器

これらを中心に、プロジェクトの特徴を踏まえ、コーディング規約として整理します。
基準の沿ったプログラミングが実施されているかを確認するには、有識者によるコーディングレビューだけでは不十分であり、解析ツールを活用する必要があります。

■ OWASP Secure Coding Practiceの概要

チェックリスト形式でプログラミングのチェックポイントを規定しています。

カテゴリ主なチェックポイント
入力検証・ホワイトリスト方式で入力を検証・正規表現や境界チェックを利用
・信頼できない入力は常に疑う
出力エンコーディング・HTML/JavaScript/CSSごとに適切なエスケープ
・テンプレートエンジン利用時もエスケープ確認
認証とパスワード管理・強力なパスワードハッシュ(bcrypt, PBKDF2, Argon2)
・多要素認証の導入
・資格情報を平文で保存しない
セッション管理・セッションIDは推測困難に
・Secure/HttpOnly クッキーを使用
・一定時間でセッションをタイムアウト
アクセス制御・最小権限の原則
・ロールベース認可
・URLやパラメータで直接権限を操作させない
暗号化・AES, RSA, ECCなど強いアルゴリズムを使用
・TLS1.2以上を利用・鍵は安全に生成・保管・廃棄
エラーハンドリングとロギング・詳細なエラーは内部ログのみに記録・利用者には一般的なメッセージのみ返す
・機微情報をログに残さない
データ保護・保存時は暗号化・転送時はTLSで暗号化
・不要になったデータは安全に削除
通信セキュリティ・HTTPSを強制
・API通信は認証+暗号化必須
・証明書検証を適切に行う
システム構成・不要サービスを停止
・セキュリティパッチを適用・既定設定のまま運用しない
データベースセキュリティ・パラメータ化クエリを使用
・動的SQLを避ける
・DBユーザは最小権限のみ付与
ファイルとリソースアクセス・ファイルパスを検証し、ディレクトリトラバーサルを防ぐ
・一時ファイルの権限管理
・外部リソースの読み込み制御
メモリ管理・C/C++でバッファオーバーフローを防止
・ポインタ操作に注意
・自動メモリ管理言語でもオブジェクト寿命を意識
モバイル・秘密情報を安全に保存(Keychain, Keystore等)
・証明書ピンニング・逆コンパイル対策
Webサービス・SOAP/REST API入力をスキーマで検証
・強力な認証・認可を導入
・不要なメソッド/エンドポイントは無効化
一般的なコーディング実践・定数の利用でマジックナンバーを避ける
・コードレビューを徹底
・セキュリティテストをCIに組み込む

■ CERT Secure Coding Standardの概要

CとJavaによるプログラミングの所作について解説しています。

・C言語

カテゴリ主な内容
環境依存OS・処理系に依存する動作を避ける改行コードや文字コードの違いに注意
整数型整数のオーバーフロー/アンダーフローを防ぐ型変換、符号付き/符号なしの混在に注意
浮動小数点型丸め誤差・精度問題に注意比較時は誤差を考慮する
文字列終端文字やバッファ境界を考慮strcpyではなくstrncpyを利用
配列境界チェックを徹底範囲外アクセスを禁止
ポインタNULLチェック・不正参照防止解放済みポインタを使用しない
動的メモリ管理メモリリーク・二重解放を防ぐfree()の後はポインタをNULLにする
構造体・共用体境界や未使用領域の扱いに注意パディング領域を意識する
式と演算子副作用や未定義動作を避けるインクリメントの多重使用を禁止
制御文可読性を高め誤解を防ぐif文には必ずブロックを使う
関数引数や戻り値を正しく扱う引数の境界検証を徹底
入出力入力検証・エラー処理を適切に行うscanfの戻り値を確認する
エラー処理戻り値チェック・例外処理を徹底戻り値を無視しない
セキュリティバッファオーバーフローやSQLi等の脆弱性防止入力サニタイズ、暗号APIの適切利用
移植性環境差異に影響されない記述固定幅整数型(int32_t等)の利用
可読性コメント・命名規則の徹底一貫したスタイルガイドを適用

・Java言語

カテゴリ主な内容
環境依存OS・処理系に依存する動作を避ける改行コードや文字コードの違いに注意
整数型整数のオーバーフロー/アンダーフローを防ぐ型変換、符号付き/符号なしの混在に注意
浮動小数点型丸め誤差・精度問題に注意比較時は誤差を考慮する
文字列終端文字やバッファ境界を考慮strcpyではなくstrncpyを利用
配列境界チェックを徹底範囲外アクセスを禁止
ポインタNULLチェック・不正参照防止解放済みポインタを使用しない
動的メモリ管理メモリリーク・二重解放を防ぐfree()の後はポインタをNULLにする
構造体・共用体境界や未使用領域の扱いに注意パディング領域を意識する
式と演算子副作用や未定義動作を避けるインクリメントの多重使用を禁止
制御文可読性を高め誤解を防ぐif文には必ずブロックを使う
関数引数や戻り値を正しく扱う引数の境界検証を徹底
入出力入力検証・エラー処理を適切に行うscanfの戻り値を確認する
エラー処理戻り値チェック・例外処理を徹底戻り値を無視しない
セキュリティバッファオーバーフローやSQLi等の脆弱性防止入力サニタイズ、暗号APIの適切利用
移植性環境差異に影響されない記述固定幅整数型(int32_t等)の利用
可読性コメント・命名規則の徹底一貫したスタイルガイドを適用

■ MISRA-C/C++の概要

組み込みに特化し、C/C++によるプログラミングの所作について解説しています。

・C言語

カテゴリ
型安全性暗黙の型変換を禁止(例:intからfloatへの暗黙変換)
ポインタNULLチェック必須、算術演算の制限
配列/文字列境界チェック必須、バッファオーバーフロー防止
制御文goto禁止、switchでdefault必須
関数再帰禁止、副作用のあるマクロ禁止
標準ライブラリ危険な関数(gets, strcpyなど)の禁止

・C++言語

カテゴリ
クラス設計多重継承制限、仮想継承の注意
例外処理非推奨、使う場合は制約付き
テンプレート部分特殊化やSFINAEの乱用禁止
キャストreinterpret_cast禁止、static_cast推奨
STL使用制限あり(特にメモリ確保や例外関連)

■ 静的解析(SAST: Static Application Security Testing)

プログラムを実行せずにソースコードやバイナリを解析し、脆弱性やバグを検出する手法です。
コードの全体を網羅的に解析できます。プログラミング段階など開発の早い段階で脆弱性を発見可能です。

代表的ツールとしては、以下があります。

・SonarQube(多言語対応、品質分析)
・Coverity(深いコード解析、産業系で利用)
・Fortify SCA
・CodeQL(GitHubが提供)

■ 動的解析(DAST: Dynamic Application Security Testing)

アプリケーションを実行し、動作中に脆弱性を検出する手法。実際の攻撃シナリオを模してテストします。実際の挙動を確認できます。実行に時間とテスト環境が必要となるため、結合テストやシステムテストにおいて実施します。

代表的ツールとしては、以下があります。

・OWASP ZAP(Webアプリの自動診断)
・Burp Suite(Webセキュリティ診断)
・AppScan
・Arachni

■ まとめ

セキュリティプログラミングは、脆弱性の発生を未然に防ぎ、安全なソフトウェアを作るための基本です。以下のように、セキュアコーディング規約の遵守、静的解析・動的解析の活用、そして運用時まで見据えた設計が不可欠です。

・設計段階での安全性考慮(入力検証、エラー処理、暗号化)
・実装時のコーディング規約遵守(OWASP、CERTなど)
・テスト工程での自動化(SAST、DAST、ペネトレーションテスト)
・リリース後の継続的改善(脆弱性対応、アップデート)

セキュリティは「後付け」ではなく、開発ライフサイクル全体に組み込む文化が必要です。

-【特集】セキュア・ソフトウェア開発ガイド, セキュリティ

執筆者:


comment

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

関連記事

セキュリティ・アーキテクチャ

対象システム/ソフトウェアにとって、インターネットのような”信頼のないネットワーク”を介して行われる攻撃が「脅威」となります。セキュリティを実現するためのアーキテクチャは、外側(防御システム)と内側( …

シングルサインオン(SSO)入門(SAML編)

シングルサインオン(SSO)は、ユーザーが一度の認証(ログイン)で、複数のシステムやサービスにアクセスできる仕組みを指します。ユーザを認証するログイン処理を一か所に統括し、アプリケーションやサービスと …

要求定義フェーズにセキュリティを組み込む

多くのセキュリティインシデントは、実装や運用以前の「要求定義フェーズ」での見落としから始まります。セキュリティは後付けできるものではなく、製品・サービスの企画段階から明示的に設計に組み込む必要がありま …

はじめての「Webセキュリティ」入門

情報セキュリティの中で、最も注視される領域がインターネットを使うWebシステムのセキュリティです。拡大しているECサイトやWebサービスでは、誰でも使える「インターネット」を介してアクセスされます。顧 …

セキュリティのためのテスト

セキュリティテストとは、システムやアプリケーションのセキュリティ対策が適切に機能しているかを検証し、脆弱性や設定不備を特定するプロセスです。目的は、攻撃を受ける前に弱点を見つけ、対策を講じることです。 …

Chinese (Simplified)Chinese (Traditional)EnglishFilipinoFrenchGermanHindiJapaneseKoreanMalayThaiVietnamese