セキュアコーディングとは、セキュリティ脆弱性の偶発的な導入を防ぐようにコンピュータソフトウェアを開発する手法です。欠陥、バグ、論理的な欠陥は、一般的に悪用されるソフトウェア脆弱性の主な原因となっています。[ 1 ]報告された何千もの脆弱性の分析を通じて、セキュリティ専門家は、ほとんどの脆弱性が比較的少数の一般的なソフトウェアプログラミングエラーに起因していることを発見しました。これらのエラーにつながる安全でないコーディング手法を特定し、開発者に安全な代替手段を教育することで、組織は展開前にソフトウェアの脆弱性を大幅に削減または排除するための積極的な措置を講じることができます。[ 2 ]
サイバーセキュリティに関連する脅威に効果的に対処するためには、適切なセキュリティをシステムに組み込むか「組み込む」必要があると、一部の学者は提唱しています。ソフトウェアにセキュリティを設計段階で組み込むことで、内部攻撃に対する保護が確保され、アプリケーションセキュリティへの脅威が軽減されます。[ 3 ]セキュアコーディングの実践は、セキュリティエンジニアリングにおけるセキュア・バイ・デザインのアプローチの一部です。
バッファオーバーフローは、一般的なソフトウェアのセキュリティ脆弱性であり、プロセスが固定長のバッファを超えるデータを格納しようとしたときに発生します。たとえば、アイテムを格納するスロットが 8 つある場合、9 つのアイテムを格納しようとすると問題が発生します。コンピュータのメモリでは、オーバーフローしたデータが次の場所のデータを上書きする可能性があり、セキュリティ脆弱性 (スタックスマッシング) やプログラムの終了 (セグメンテーション違反) につながる可能性があります。[ 1 ]
バッファオーバーフローを起こしやすいCプログラムの例は次のとおりです。
#include <string.h>#define SMALL 50void vulnerable_function ( char * large_user_input ) { char dst [ SMALL ]; strcpy ( dst , large_user_input ); }ユーザー入力が宛先バッファよりも大きい場合、バッファオーバーフローが発生します。
この安全でないプログラムを修正するには、strncpyを使用してバッファオーバーフローの可能性を防いでください。
#include <string.h>#define BUF_SIZE 100void secure_function ( char * user_input ) { char dst [ BUF_SIZE ]; // 最大 BUF_SIZE バイトをコピーしますstrncpy ( dst , user_input , BUF_SIZE ); // バッファの最後の文字を NUL に設定します。dst [ BUF_SIZE - 1 ] = '\0' ; }別の安全な代替手段として、 mallocを使用してヒープ上にメモリを動的に割り当てる方法があります。
#include <stdlib.h> #include <string.h>char * secure_copy ( char * src ) { size_t len = strlen ( src ); char * dst = ( char * ) malloc ( len + 1 ); if ( dst ) { strncpy ( dst , src , len ); // ヌル終端文字を追加dst [ len ] = '\0' ; } return dst ; }上記のコードスニペットでは、プログラムはの内容をsrcにコピーしようと試みるdstと同時に、の戻り値をチェックして、malloc()宛先バッファに十分なメモリが割り当てられていることを確認します。
フォーマット文字列攻撃とは、悪意のあるユーザーが特定の入力を提供し、それが最終的にprintf()などのフォーマットを実行する関数の引数として入力される攻撃です。この攻撃では、攻撃者はスタックから読み取ったり、スタックに書き込んだりします。
C言語のprintf関数は、標準出力に出力します。printf関数の引数が適切にフォーマットされていない場合、いくつかのセキュリティ上の脆弱性が生じる可能性があります。以下は、フォーマット文字列攻撃に対して脆弱なプログラムです。
#include <stdio.h>void vulnerable_print ( char * malicious_input ) { printf ( malicious_input ); }プログラムに渡される悪意のある引数は「%s%s%s%s%s%s%s」である可能性があり、これは不適切なメモリ読み取りによってプログラムをクラッシュさせる可能性があります。
整数オーバーフローとは、算術演算の結果、使用可能なメモリ領域内に収まらないほど大きな整数が生成された場合に発生する現象です。整数オーバーフローを適切にチェックしないプログラムは、潜在的なソフトウェアバグや脆弱性を引き起こす可能性があります。
以下は、xとyの合計が定義値MAX以下であることを確認するC++関数です。
#define MAX 5000bool sum_is_valid_flawed ( unsigned int x , unsigned int y ) { unsigned int sum = x + y ; return sum <= MAX ; }このコードの問題点は、加算演算における整数オーバーフローをチェックしていないことです。xとyの合計が整数の最大値を超えるとunsigned int、加算演算でオーバーフローが発生し、xとyの合計が最大値よりも大きい場合でも、結果として最大値以下の値になる可能性があります。
以下に示す関数は、合計がxとyの両方以上であることを確認することでオーバーフローをチェックします。合計がオーバーフローした場合、合計はxまたはyより小さくなります。
#define MAX 5000bool sum_is_valid_secure ( unsigned int x , unsigned int y ) { unsigned int sum = x + y ; return sum >= x && sum >= y && sum <= MAX ; }パス・トラバーサルとは、信頼できないソースから提供されたパスが、不正なファイルアクセスを可能にするような方法で解釈される脆弱性のことです。
例えば、ファイル名を受け取って記事を取得するスクリプトを考えてみましょう。スクリプトはそのファイル名を読み込んで解析します。このようなスクリプトは、犬の餌に関する記事を取得するために、次のような架空のURLを使用するかもしれません。
https://www.example.net/cgi-bin/article.sh?name=dogfood.htmlスクリプトに入力チェック機能がなく、ファイル名が常に有効であると仮定している場合、悪意のあるユーザーはURLを偽造してWebサーバーから設定ファイルを取得する可能性があります。
https://www.example.net/cgi-bin/article.sh?name=../../../../../etc/passwdスクリプトによっては、/etc/passwdファイルが公開される可能性があります。Unix系システムでは、このファイルには(その他にも)ユーザー ID、ログイン名、ホームディレクトリのパス、シェルなどが含まれています。(同様の攻撃については、 SQL インジェクションを参照してください。)