Your time is limited, so don’t waste it living someone else’s life.
この記事は自分用の備忘録です。
ファジングとは?
ソフトウェアの脆弱性を発見する検査方法
異常データ(ファズと呼ぶ)を大量に送り込み、挙動を監視する
ファジングツールを使って自動化するのが一般的
未知の攻撃に対応しやすい手段らしい
異常系テストってこと?
ファジングは「異常系テスト」の一種で、分類としては「ブラックボックステスト」
ただし、ニュアンスとしては
「プログラムの中身を気にせず、自動的に大量の異常データを送り込んで確認する」
という、質より量を重視したアプローチだとか
例えばどんな異常データを送るの?
文字列の異常データ
- 長すぎる文字列
- 送るデータ
- 通常の入力サイズを大幅に超えるような、非常に長い文字列
- 起こる問題
- バッファオーバーフローを引き起こし、メモリの破壊やクラッシュ、場合によっては任意のコード実行につながる
- 送るデータ
- 不正な文字
- 送るデータ
- 特殊文字、エスケープシーケンス(例:\n, \t)、SQLインジェクションを狙った文字列(例:' OR '1'='1)
- 起こる問題
- プログラムの処理を混乱させ、セキュリティホールや意図しない動作(例:データベースの不正操作やシステムの制御権を奪う)を引き起こす
- 送るデータ
- 文字コードの異常
- 送るデータ
- UTF-8やASCII以外の文字コード、または無効な文字コードを含む文字列
- 起こる問題
- 文字列のエンコードやデコード処理でエラーが発生し、データの破損、表示不具合、さらにはセキュリティリスクが発生する
- 送るデータ
他にも
- 数値の異常データ
- データ形式に異常があるデータ
- タイミングや状態に依存したデータ
- 異常なバイナリデータ
- プロトコルの異常データ
など
どうやって使うの?
GoogleさんがGitHubで公開してくれているよ
もしRSpecで頑張って書いたらどうなる?
GPTに聞いてみた
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触ってないけれど、たぶん大変そうな気がした。
感想
異常系テストで「途中で電源が落ちた場合」や「壊れたバイナリの場合」みたいな例外についてはツール使ったほうが良さそう。少しテストについて詳しくなった。
参考