Goセキュアコーディングガイド 02.1 - バリデーション

"Validation" from go-scp

Goセキュアコーディングガイドのバリデーションの日本語意訳になります。


バリデーション

バリデーションチェックでは、期待したデータをユーザーが実際に入力していることを保証するために、ユーザーの入力を一連の条件に対してチェックします。

重要: バリデーションが失敗した場合、入力は拒否されなければなりません。

これはセキュリティの観点からだけではなく、データは通常様々なシステムやアプリケーションにまたがって使用されるため、データの一貫性と完全性の観点からも重要です。

この記事では、開発者がGoでWebアプリケーションを開発する際に注意すべき、セキュリティリスクをリストアップしています。

ユーザーインタラクション性

ユーザーの入力を許可するアプリケーションのあらゆる部分が、潜在的なセキュリティリスクです。
アプリケーションのハッキング方法を探している悪意のあるプログラムだけでなく、ヒューマンエラーによる間違った入力が問題を発生させることもあります。
(統計的には、不正なデータの状態の大部分はヒューマンエラーによって起こっています。)
Goでは、このような問題から保護するためにいくつかの方法があります。

Goには、そのようなエラーが起こらないようにするためのメソッドを含んだ、ネイティブライブラリがあります。
文字列を扱うときは、次のようなパッケージを使用することができます。

例:

  • strconv パッケージはstring型から他のデータ型への変換を扱います。
  • strings パッケージはstring型を扱う全ての関数を持っています。
  • [regexp][4] パッケージは独自フォーマットに対応するための正規表現をサポートしています。[^1]
  • [utf8][9] パッケージはUTF-8でエンコードされたテキストをサポートする関数や定数を実行しており、Rune型とUTF-8バイト列を変換する関数を持っています。

UTF-8エンコードされたRuneのバリデーション
* Valid
* ValidRune
* ValidString

UTF-8 Runeのエンコード
* EncodeRune

UTF-8 のデコード
* DecodeLastRune
* DecodeLastRuneInString
* DecodeRune
* DecodeRuneInString

注意: Goでは FormStringMap 値として扱います。

データの正当性を保証する他のテクニック:

  • ホワイトリスト化 - 可能な限り、許可された文字のホワイトリストによる入力値チェックをする。[バリデーション - タグの除去][1]を参照。
  • 境界値チェック - データとその長さの両方を検証すること。
  • 文字列エスケープ - 単一クォートのような特殊文字向け。
  • 数値バリデーション - 入力が数値の場合。
  • Nullバイトチェック - (%00)
  • 改行コードチェック - %0d, %0a, \r, \n
  • パス変更文字のチェック - ../\\..
  • 拡張UTF-8のチェック - 特殊文字の代替表現形式のチェック

注意: HTTPリクエストとレスポンスのヘッダーには、ASCII文字のみを含んでいることを保証してください。

Goでセキュリティを扱うためのサードパーティパッケージがあります。

  • [Gorilla][6] - Webアプリケーションセキュリティで最もよく利用されるパッケージの一つ
    websockets, cookie sessions, RPC 等々 をサポートしています。

  • [Form][7] - url.Values をGoの値にエンコードしたり、Goの値を url.Values にデコードしたりします。
    二重 ArrayMap の全てをサポートしています。

  • [Validator][8] - Goの構造体や構造体フィールドのバリデーションを行います。スライスや配列の分割だけでなく、混在 フィールド, 混在 構造体, Map を含みます。

ファイル操作

ファイル操作の大半ではユーザーデータを処理するため、
ファイルの使用が必要な場合には(読み取り書き込み)、バリデーションを行うべきです。

他のファイルチェック手順として、指定したファイル名が存在するかどうかの「ファイル存在チェック」が含まれます。

追加のファイル情報は[ファイル管理][2]セクションにあり、「エラー処理」に関する情報は[エラー処理][3]セクションにあります。

データソース

信頼性の高いソースから信頼性の低いソースにデータが渡される場合、完全性チェックを行う必要があります。
これによって、データが改ざんされておらず、意図したデータを受信していることを保証できます。
他のデータソースチェックには以下が含まれます。

  • システム間の整合性チェック
  • ハッシュトータル
  • 参照整合性

注意: 現代のリレーショナルデータベースにおいては、もし主キーの値がDBの内部機構によって制約がかかっていない場合、その値をバリデーションすべきです。

  • 一意性チェック
  • テーブル探索チェック


ポスト・バリデーション アクション

データバリデーションのベストプラクティスによると、入力値バリデーションはデータバリデーションガイドラインの最初の部分にすぎません。
_ポスト・バリデーション アクション_も行う必要があります。
_ポスト・バリデーション アクション_はコンテキストにより異なり、3つのカテゴリに分けられます。

  • エンフォースメント アクション(強制化アクション)

アプリケーションとデータをより安全にするために、いくつかの種類の_エンフォースメント アクション_があります。

  • 送信されたデータが条件を満たしておらず、その条件を満たすために変更が必要な旨をユーザーに通知してください。

  • サーバー側でユーザーが送信したデータを変更します。ユーザーに通知はしません。この方法はインタラクティブなシステムに向いています。

注: 後者は主に表示上の変更で使われます。(機密性の高いユーザーデータの変更は、データロスを引き起こしてしまう、文字の切り捨てのような問題を引き起こす可能性があります。)

  • アドバイザリーアクション(忠告アクション)

アドバイザリーアクションは通常、入力されたデータを変更せずに受け入れますが、そのデータにエラーがあることを入力元に対して通知します。これは非インタラクティブなシステムに向いています。

  • ベリフィケーションアクション(検証アクション)

ベリフィケーションアクションはアドバイザリーアクションの特殊なケースです。
このケースでは、ユーザーがデータを送信すると、システムがユーザーに対してそのデータを確認するように問いかけ、変更を提案します。ユーザーはその変更を受け入れるか、変更前の入力値を使うようにします。

これを説明する簡単な方法は、請求先住所フォームです。
ユーザーは住所を入力し、システムはアカウントに紐付いた住所を提案します。
ユーザーはこれらの住所か、または最初に入力したお届け先住所を使用することができます。


次: 02.2 - サニタイズ

 
comments powered by Disqus