【基本情報】独学マラソン ファジング Day 11

Your time is limited, so don’t waste it living someone else’s life.

:::note worn
この記事は自分用の備忘録です。
:::



# ファジングとは？

ソフトウェアの脆弱性を発見する検査方法
異常データ（ファズと呼ぶ）を大量に送り込み、挙動を監視する
ファジングツールを使って自動化するのが一般的
未知の攻撃に対応しやすい手段らしい

https://www.hitachi-solutions.co.jp/defensics/

# 異常系テストってこと？
ファジングは「異常系テスト」の一種で、分類としては「ブラックボックステスト」

ただし、ニュアンスとしては

「プログラムの中身を気にせず、自動的に大量の異常データを送り込んで確認する」

という、質より量を重視したアプローチだとか

# 例えばどんな異常データを送るの？

### 文字列の異常データ
- 長すぎる文字列
    - 送るデータ
        - 通常の入力サイズを大幅に超えるような、非常に長い文字列
    - 起こる問題
        - バッファオーバーフローを引き起こし、メモリの破壊やクラッシュ、場合によっては任意のコード実行につながる
- 不正な文字
    - 送るデータ
        - 特殊文字、エスケープシーケンス（例：\n, \t）、SQLインジェクションを狙った文字列（例：' OR '1'='1）
    - 起こる問題
        - プログラムの処理を混乱させ、セキュリティホールや意図しない動作（例：データベースの不正操作やシステムの制御権を奪う）を引き起こす
- 文字コードの異常
    - 送るデータ
        - UTF-8やASCII以外の文字コード、または無効な文字コードを含む文字列
    - 起こる問題
        - 文字列のエンコードやデコード処理でエラーが発生し、データの破損、表示不具合、さらにはセキュリティリスクが発生する

<br>

他にも
- 数値の異常データ
- データ形式に異常があるデータ
- タイミングや状態に依存したデータ
- 異常なバイナリデータ
- プロトコルの異常データ

など

# どうやって使うの？
GoogleさんがGitHubで公開してくれているよ

https://github.com/google/oss-fuzz

# もしRSpecで頑張って書いたらどうなる？

GPTに聞いてみた

```ruby:fuzzing_spec.rb
# spec/fuzzing_spec.rb
RSpec.describe 'Fuzzing tests' do
  let(:subject) { YourClass.new }

  describe '異常な文字列データのテスト' do
    it '長すぎる文字列を処理できるか' do
      long_string = 'a' * 10000
      expect { subject.process(long_string) }.not_to raise_error
    end

    it 'さらに長すぎる文字列を処理できるか' do
      even_longer_string = 'a' * 50000
      expect { subject.process(even_longer_string) }.not_to raise_error
    end

    it '不正な特殊文字を処理できるか' do
      invalid_string = "' OR '1'='1"
      expect { subject.process(invalid_string) }.not_to raise_error
    end

    it '改行コードを含む文字列を処理できるか' do
      newline_string = "test\nstring"
      expect { subject.process(newline_string) }.not_to raise_error
    end

    it 'タブ文字を含む文字列を処理できるか' do
      tabbed_string = "test\tstring"
      expect { subject.process(tabbed_string) }.not_to raise_error
    end

    it 'エスケープシーケンスを含む文字列を処理できるか' do
      escape_string = "test\\string"
      expect { subject.process(escape_string) }.not_to raise_error
    end

    it '無効な文字コードを処理できるか' do
      invalid_encoding_string = "test\xFF"
      expect { subject.process(invalid_encoding_string) }.not_to raise_error
    end

    it '無限にネストされた文字列を処理できるか' do
      nested_string = '[' * 1000 + ']' * 1000
      expect { subject.process(nested_string) }.not_to raise_error
    end
  end

  describe '異常な数値データのテスト' do
    it '極端に大きい数値を処理できるか' do
      large_number = 10**100
      expect { subject.process(large_number) }.not_to raise_error
    end

    it '極端に小さい数値を処理できるか' do
      small_number = -10**100
      expect { subject.process(small_number) }.not_to raise_error
    end

    it 'NaNを処理できるか' do
      invalid_number = Float::NAN
      expect { subject.process(invalid_number) }.not_to raise_error
    end

    it 'Infinityを処理できるか' do
      infinite_number = Float::INFINITY
      expect { subject.process(infinite_number) }.not_to raise_error
    end

    it '負のInfinityを処理できるか' do
      negative_infinity = -Float::INFINITY
      expect { subject.process(negative_infinity) }.not_to raise_error
    end

    it '非常に小さい浮動小数点数を処理できるか' do
      small_float = 10**-100
      expect { subject.process(small_float) }.not_to raise_error
    end

    it '非常に大きい浮動小数点数を処理できるか' do
      large_float = 10**100
      expect { subject.process(large_float) }.not_to raise_error
    end
  end

  describe '異常なデータ形式のテスト' do
    it '壊れたJSONデータを処理できるか' do
      invalid_json = '{"key": "value", "key2":' # JSONが壊れている
      expect { subject.process(invalid_json) }.not_to raise_error
    end

    it '壊れたXMLデータを処理できるか' do
      invalid_xml = '<root><element></root>' # XMLタグが不正
      expect { subject.process(invalid_xml) }.not_to raise_error
    end

    it '壊れたCSVデータを処理できるか' do
      invalid_csv = 'id,name\n1,John\n2,' # CSVデータが不完全
      expect { subject.process(invalid_csv) }.not_to raise_error
    end
  end
end

```

1年ぐらいRails触ってないけれど、たぶん大変そうな気がした。



# 感想
異常系テストで「途中で電源が落ちた場合」や「壊れたバイナリの場合」みたいな例外についてはツール使ったほうが良さそう。少しテストについて詳しくなった。


# 参考

https://wa3.i-3-i.info/word13074.html

https://adoc-teslab.com/blog/non-nominal-testing/25181/

https://www.gmo.jp/security/cybersecurity/penetration-testing/blog/fuzzing/

https://www.lrm.jp/security_magazine/fuzzing_overview/

https://qiita.com/snsk/items/efb826f8d419b8fbfc49