🛡 Seguridad 🔤 Fuzzing cargo-fuzz libFuzzer AFL++

Diccionario de Fuzzing

Auditoría de seguridad del parser CultivaConfig v1.0 — TOML · JSON · CultivaRC

Cobertura sin diccionario
34%
Cobertura estimada con diccionario
81%
Entradas en diccionario
94
Formatos cubiertos
3
📋
Contexto del Target
Rust
Lenguaje
cargo-fuzz
Fuzzer
libFuzzer
Backend
3
Formatos
v1.0-rc
Versión
El parser rechaza inputs sin firma válida en el primer byte — el fuzzing aleatorio nunca llega al 65% del código. Un diccionario con magic bytes y palabras clave elimina esta barrera de validación temprana.
📜
Diccionario Principal — cultivarc.dict
cultivarc.dict dict
# =====================================================================
# cultivarc.dict — Diccionario de fuzzing para CultivaConfig parser
# Target: parse_config (TOML · JSON · CultivaRC propietario)
# Generado para: cargo fuzz run fuzz_parse -- -dict=./cultivarc.dict
# Versión: 1.0  |  Entradas: 94  |  CULTIVA IA Security Audit 2026
# =====================================================================

# ──────────────────────────────────────────────
# SECCIÓN 1: Magic bytes y firmas de formato
# ──────────────────────────────────────────────

# CultivaRC: firma propietaria (0xC0 0x1A = "Cultiva")
cultivarc_magic="\xC0\x1A\x00\x01"
toml_bom="\xEF\xBB\xBF"
json_bom="\xEF\xBB\xBF{"

# ──────────────────────────────────────────────
# SECCIÓN 2: CultivaRC — formato propietario
# ──────────────────────────────────────────────

# Cabeceras de sección
"[agent:"
"[workflow:"
"[model:"
"[tool:"
"[datasource:"
"[pipeline:"
"[schedule:"
"[output:"
"[*]"

# Directivas especiales
include_kw="!include"
extends_kw="!extends"
override_kw="!override"
secret_kw="!secret"
env_kw="!env"

# Variables de entorno
var_open="${"
var_close="}"
"${CULTIVA_API_KEY}"
"${MODEL_ENDPOINT}"
"${MAX_TOKENS}"

# Claves de configuración de agente
"model"
"temperature"
"max_tokens"
"system_prompt"
"tools"
"memory"
"timeout_ms"
"retry_limit"
"stream"

# Valores booleanos y especiales
"true"
"false"
"null"
"~"
"none"

# ──────────────────────────────────────────────
# SECCIÓN 3: TOML
# ──────────────────────────────────────────────

# Tipos de valores TOML
"[[agents]]"
"[[tools]]"
"[package]"
"[dependencies]"

# Literales TOML
toml_inf="inf"
toml_nan="nan"
toml_date="1979-05-27T07:32:00Z"
toml_multiline="\"\"\""
toml_raw_str="'''"

# Caracteres especiales TOML
"."
"="
"#"
","
"["
"]"

# ──────────────────────────────────────────────
# SECCIÓN 4: JSON
# ──────────────────────────────────────────────

"{"
"}"
"["
"]"
json_null="null"
json_true="true"
json_false="false"
json_colon=":"

# Escapes JSON en strings
json_esc_nl="\\n"
json_esc_tab="\\t"
json_esc_bs="\\\\"
json_esc_q="\\\""
json_unicode="\\u0000"
json_unicode_high="\\uFFFF"
json_surrogate="\\uD800\\uDC00"

# ──────────────────────────────────────────────
# SECCIÓN 5: Valores boundary (aritmética)
# ──────────────────────────────────────────────

zero="0"
neg_one="-1"
i32_max="2147483647"
i32_min="-2147483648"
i64_max="9223372036854775807"
u64_max="18446744073709551615"
float_inf="1.7976931348623157e+308"
float_neg_inf="-1.7976931348623157e+308"

# ──────────────────────────────────────────────
# SECCIÓN 6: Caracteres peligrosos y path traversal
# ──────────────────────────────────────────────

path_traversal="../"
path_abs="/etc/passwd"
null_byte="\x00"
crlf="\r\n"
lf="\n"
tab="\t"
unicode_bom="\xEF\xBB\xBF"
unicode_replacement="\xEF\xBF\xBD"
overlong_utf8="\xC0\xAF"
94 entradas en rango óptimo (50–200). Cubre las 3 capas del parser: detección de formato, parsing de estructura y validación de valores.
📄
Diccionario Complementario — json_supplement.dict
json_supplement.dict dict
# json_supplement.dict — Tokens JSON adicionales para deep-path fuzzing
# Uso: cargo fuzz run fuzz_parse -- -dict=cultivarc.dict -dict=json_supplement.dict

# Números especiales JSON
"1e308"
"1e-308"
"0.0"
"-0"
"0e0"
"1.0e+1"

# Strings con longitud extrema (ayuda a fuzz length handling)
empty_str=""
space_str=" "

# Estructuras anidadas profundas
"[[["
"]]]]"
"{{{"
"}}}}"

# Claves duplicadas (comportamiento no especificado en JSON)
"::"
",,"
",]"
"[,"
"{,"
"{"

# Control characters en strings
ctrl_a="\x01"
ctrl_z="\x1A"
del_char="\x7F"
form_feed="\x0C"
Comandos de Uso
cargo-fuzz (recomendado) bash
# Build con sanitizers
cargo fuzz build fuzz_parse

# Run con diccionario principal
cargo fuzz run fuzz_parse -- \
  -dict=./cultivarc.dict \
  -max_len=4096 \
  -print_final_stats=1

# Run con ambos diccionarios
cargo fuzz run fuzz_parse -- \
  -dict=./cultivarc.dict \
  -dict=./json_supplement.dict \
  -max_len=16384 \
  -timeout=30
AFL++ (alternativo) bash
# Compilar con afl-clang-lto para AUTODICTIONARY
export AFL_LLVM_DICT2FILE=auto.dict
afl-clang-lto++ parse_config.cc -o target

# Combinar diccionarios
cat cultivarc.dict json_supplement.dict \
  auto.dict > combined.dict | sort -u

# Fuzz con diccionario combinado
afl-fuzz \
  -x combined.dict \
  -i ./corpus_in \
  -o ./afl_out \
  -- ./target @@
Generación automática desde código fuente del parser bash
# Extraer strings del binario compilado
strings ./target/debug/parse_config \
  | grep -E '^[a-zA-Z!$\[{][a-zA-Z0-9_:!$\[\]{}.-]{2,30}$' \
  | sed 's/^/"/; s/$/"/' \
  | sort -u >> cultivarc.dict

# Extraer tokens de comparación del código fuente Rust
grep -ohP '"[^"]{1,40}"' src/parser/*.rs \
  | sort -u \
  | grep -v '//' \
  >> cultivarc.dict

# Deduplicar el diccionario final
sort -u cultivarc.dict -o cultivarc.dict
wc -l cultivarc.dict  # Verificar recuento
🚀
Plan de Implementación
1

Copiar diccionarios al directorio de fuzzing

Colocar cultivarc.dict y json_supplement.dict en fuzz/dictionaries/ junto al harness existente.

2

Crear corpus semilla mínimo

Añadir 5-10 ficheros válidos de cada formato a fuzz/corpus/. El diccionario + corpus sinérgicamente maximizan la cobertura temprana.

3

Ejecutar baseline sin diccionario

Correr cargo fuzz run fuzz_parse -- -max_total_time=300 y guardar las métricas. Cobertura esperada: ~34%.

4

Ejecutar con diccionario y comparar

Añadir -dict=./fuzz/dictionaries/cultivarc.dict y repetir por el mismo tiempo. Cobertura esperada: >75%. Comparar con -print_final_stats=1.

5

Refinar diccionario con tokens descubiertos

Analizar nuevas rutas de código alcanzadas e identificar keywords adicionales en el parser. Añadirlas al diccionario y repetir el ciclo.

📈
Cobertura Estimada por Módulo del Parser
Módulo Función Sin dict Con dict Tokens clave
format_detector Detección de formato por magic bytes 12% 98% \xC0\x1A, \xEF\xBB\xBF
toml_parser Parsing de tablas, arrays e inline tables 28% 83% [[ ]], inf, nan, '''
json_parser Parsing de objetos, arrays, valores 41% 87% \uD800, \x00, 1e308
cultivarc_parser Secciones [agent:], directivas !, variables ${} 19% 76% !include, ${, [agent:
value_validator Validación de tipos y rangos numéricos 52% 91% i64_max, u64_max, -1
path_resolver Resolución de rutas en !include 8% 64% ../, /etc/passwd, \x00
Anti-patrones Detectados y Correcciones
✗ Anti-patrón: entrada demasiado larga
"This is the full configuration section for a CultivaRC agent workflow pipeline with model settings"
El fuzzer necesita tokens atómicos. Frases completas desperdician el presupuesto de mutación.
✓ Correcto: tokens individuales
"[agent:" "workflow" "pipeline" "model"
Cada token por separado permite al fuzzer combinarlos creativamente.
✗ Anti-patrón: bytes sin escapar
# Byte 0xC0 sin escapar: cultivarc_magic="ÀZ"
Los bytes no-ASCII se mangled dependiendo del encoding del sistema.
✓ Correcto: hex escapes explícitos
cultivarc_magic="\xC0\x1A\x00\x01"
Las secuencias \xXX son portables y unívocos entre plataformas.
✗ Anti-patrón: diccionario masivo
# 2.000 entries from grep + strings + LLM # Cubre todo pero diluye tokens útiles
Con más de 500 entradas el fuzzer diluye el presupuesto en tokens irrelevantes.
✓ Correcto: foco en 50-200 tokens
# 94 entradas enfocadas en: # 1) Magic bytes (crítico) # 2) Keywords del dominio # 3) Boundary values
Un diccionario pequeño y preciso supera siempre a uno exhaustivo.
📃
Resumen por Herramienta
Fuzzer Flag de diccionario Soporte multi-dict Auto-generación Notas
cargo-fuzz recomendado -- -dict=./dict Sí (múltiples -dict) No nativo Usa backend libFuzzer; todos los flags de libFuzzer aplican
libFuzzer -dict=./dict No nativo Métrica efectividad con -print_final_stats=1
AFL++ -x ./dict Sí (múltiples -x) AFL_LLVM_DICT2FILE AUTODICTIONARY con afl-clang-lto para extracción de comparaciones
go-fuzz No soportado No No Alternativa: inyectar tokens como corpus files via base64