📋
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 |
Sí | 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 |