Referencia del DSL .sca — StaticCodeAudit por CodeFixture
Este documento describe la sintaxis completa de los archivos de reglas .sca. Cada archivo define una regla de detección autónoma.
1. Estructura de una regla
Un archivo .sca contiene una sola regla. Estructura mínima:
rule mon_id_de_regle
language python
severity HIGH
match
pattern mon_pattern_regex
end
risk
en: English risk description
fr: Description du risque en français
end
solution
en: English fix
fr: Correction en français
end
end
rule_id debe estar en minúsculas y solo con guiones bajos: [a-z0-9_]+2. Palabras clave de la regla
| Palabra clave | Valores | Obligatorio | Descripción |
|---|---|---|---|
language | python, javascript, java, csharp, php, html, yaml, dockerfile | requerido | Lenguaje del código analizado |
severity | CRITICAL, HIGH, MEDIUM, LOW, INFO | requerido | Severidad del finding |
category | security, arch, ui, ux, maintenance, cicd | opcional | Categoría (predeterminado: security) |
confidence | 0 a 100 | opcional | Confianza en % (predeterminado: 80) |
3. Bloque match (detección por patrón)
El bloque match define los patrones a detectar en el código. Repetible (varios bloques = OR).
3.1 Palabras clave del bloque match
| Palabra clave | Tipo | Descripción |
|---|---|---|
pattern | Regex | Expresión regular a buscar |
text | Texto plano | Texto escapado automáticamente. * = comodín (cualquier cosa) |
with | Regex | El contexto debe contener también este patrón |
with-text | Texto plano | Como with pero escapado automáticamente |
pattern-not | Regex | El contexto no debe contener este patrón |
text-not | Texto plano | Como pattern-not pero escapado |
scope | Valor | Alcance de la búsqueda (ver más abajo) |
3.2 Scopes
| Scope | Comportamiento del pattern | Comportamiento del pattern-not |
|---|---|---|
line | Verificado línea por línea | Verificado en la misma línea |
context-N | Verificado en ventanas de N líneas | Verificado en el bloque entero de N líneas |
file | Verificado en el archivo completo | Verificado en el archivo completo |
3.3 text vs pattern
text — para todos los desarrolladores. La herramienta escapa automáticamente los caracteres especiales. El * significa "cualquier cosa".
match
text .execute(
with-text f"*"
scope context-4
end
pattern — para expertos en regex. El patrón se utiliza tal cual.
match
pattern \.execute\s*\(.*f["']
scope context-4
end
Ambos ejemplos anteriores detectan el mismo código.
4. Bloque requires (condiciones de archivo)
El bloque requires define condiciones sobre el archivo. Si se utiliza solo (sin match), el finding se sitúa a nivel de archivo (línea 1). Si se combina con match, sirve como prefiltro.
| Palabra clave | Lógica | Descripción | Ejemplo |
|---|---|---|---|
has | TODOS deben coincidir | El contenido del archivo debe contener este patrón | has @app\.route |
not_has | NINGUNO debe coincidir | El contenido del archivo NO debe contener este patrón | not_has logging |
min_lines | ≥ N | El archivo debe tener al menos N líneas | min_lines 500 |
path_contains | AL MENOS UNO debe coincidir | La ruta del archivo debe contener este segmento | path_contains vendor/ |
not_path_has_file | NINGUNO debe existir | El directorio del archivo NO debe contener este archivo | not_path_has_file LICENSE |
has, not_has, path_contains y not_path_has_file son repetibles (varias líneas = varias condiciones).Ejemplos
# Archivo Flask sin logging
requires
has @app\.route
not_has import\s+logging
end
# Archivo demasiado largo
requires
min_lines 500
end
# Código vendor sin LICENSE
requires
path_contains vendor/
not_path_has_file LICENSE
not_path_has_file LICENSE.md
end
5. Análisis taint (source → sink)
El análisis taint rastrea el flujo de datos desde sources (entradas del usuario) hasta sinks (funciones peligrosas), salvo que intervenga un sanitizer.
| Palabra clave | Sintaxis | Descripción |
|---|---|---|
source | source <regex> kind=<type> | Origen de los datos no confiables |
sink | sink <regex> | Función peligrosa que recibe los datos |
sanitizer | sanitizer <regex> | Función que neutraliza los datos |
Tipos de sources (kind=): http, stdin, cli, env, file, network
rule taint_sqli
language python
severity HIGH
source request\.args\.get\( kind=http
source request\.form\[ kind=http
source input\s*\( kind=stdin
sink \.execute\s*\(
sink \.executemany\s*\(
sanitizer \bint\s*\(
sanitizer psycopg2\.sql\.SQL
end
6. Bloques i18n (risk, solution, message)
Los bloques risk, solution, benefit y message admiten traducción en 4 idiomas:
risk
en: User input in SQL query allows injection.
fr: Entrée utilisateur dans la requête SQL permet l'injection.
es: Entrada de usuario en consulta SQL permite inyección.
de: Benutzereingabe in SQL-Abfrage ermöglicht Injection.
end
en, fr, es, de. El informe utiliza el idioma configurado en --lang.7. Bloque metadata (CWE, CVE, OWASP, ISO, WCAG)
metadata
cwe CWE-89
cwe CWE-90
cve CVE-2021-44228
owasp A03:2021
iso27001 A.8.28 A.8.25
asvs 5.3.4
wcag 1.1.1
end
| Clave | Formato | Descripción |
|---|---|---|
cwe | CWE-NNN (multi) | Common Weakness Enumeration. Múltiples valores mediante líneas repetidas o tokens separados por espacios. |
cve | CVE-YYYY-NNNN (multi) | CVE específico para el cual se creó la regla. Se muestra como enlace clickable a NVD. |
owasp | ANN:YYYY | OWASP Top 10 |
iso27001 | A.N.NN (multi) | ISO/IEC 27001:2022 Anexo A |
asvs | N.N.N (multi) | OWASP ASVS |
wcag | N.N.N (multi) | Criterio W3C WCAG 2.1 (utilizado por las reglas de accesibilidad en lugar de CWE). |
Todas las claves multi-valor (cwe, cve,
iso27001, asvs, wcag) aceptan
varios tokens en la misma línea (cwe CWE-89 CWE-90)
o líneas repetidas — los valores se acumulan.
La clasificación metadata se propaga a todos los exports:
HTML (enlaces clickables), JSON (objeto finding.compliance)
y SARIF (rule.properties.tags).
8. Modos de ejecución
El modo se infiere automáticamente a partir de los bloques presentes:
| Bloques presentes | Modo inferido |
|---|---|
match (pattern/text) | regex |
requires solo (has/not_has/min_lines) | file_contains |
match + requires | regex con prefiltro de archivo |
source + sink | taint |
source + sink + match | regex+taint |
hook | python_hook (reglas custom avanzadas) |
mode explícitamente; se recomienda la inferencia automática.9. Ejemplos completos
9.1 Detección simple (texto plano)
rule console_log_residual
language javascript
severity LOW
category ux
match
text console.log(
end
risk
en: console.log() calls left in production code.
fr: Appels console.log() laissés en production.
end
solution
en: Remove console.log() or use a logging system.
fr: Supprimer les console.log() ou utiliser un système de logging.
end
end
9.2 Pattern con exclusión (context)
rule insecure_cookie
language python
severity MEDIUM
match
pattern \.set_cookie\s*\(
pattern-not (?:httponly\s*=\s*True|secure\s*=\s*True)
scope context-4
end
risk
en: Cookie without HttpOnly/Secure flags.
fr: Cookie sans flags HttpOnly/Secure.
end
solution
en: Add httponly=True, secure=True, samesite="Lax".
fr: Ajouter httponly=True, secure=True, samesite="Lax".
end
end
9.3 Condición de archivo solamente
rule file_too_long
language python
severity LOW
category arch
requires
min_lines 500
end
risk
en: Very long files are difficult to maintain.
fr: Les fichiers très longs sont difficiles à maintenir.
end
solution
en: Split into smaller, focused modules.
fr: Découper en modules plus petits et focalisés.
end
end
9.4 Combinación match + requires
rule missing_auth_decorator
language python
severity MEDIUM
match
pattern @app\.route\s*\(\s*[\"'](?:/admin|/api/delete)
pattern-not @login_required
scope context-4
end
risk
en: Admin route without authentication decorator.
fr: Route admin sans décorateur d'authentification.
end
solution
en: Add @login_required on all sensitive routes.
fr: Ajouter @login_required sur toutes les routes sensibles.
end
end
9.5 Análisis taint (inyección SQL)
rule taint_sqli
language python
severity HIGH
confidence 90
source request\.args\.get\( kind=http
source request\.form\[ kind=http
sink \.execute\s*\(
sink \.executemany\s*\(
sanitizer psycopg2\.sql\.SQL
sanitizer \bint\s*\(
risk
en: Tainted data flows into SQL query without parameterization.
fr: Données non fiables atteignent une requête SQL sans paramétrage.
end
solution
en: Use parameterized queries with placeholders (%s, ?).
fr: Utilisez des requêtes paramétrées avec placeholders (%s, ?).
end
metadata
cwe CWE-89
owasp A03:2021
end
end
9.6 Verificación de gobernanza vendor
rule unreviewed_vendor_code
language python
severity LOW
category maintenance
requires
path_contains vendor/
path_contains third-party/
not_path_has_file LICENSE
not_path_has_file NOTICE
end
risk
en: Vendor code without LICENSE file.
fr: Code tiers sans fichier LICENSE.
end
solution
en: Add LICENSE file to vendor directories.
fr: Ajouter un fichier LICENSE aux répertoires vendor.
end
end
10. Glosario
| Término | Definición |
|---|---|
| DSL | Domain-Specific Language — lenguaje dedicado a la definición de reglas de auditoría |
| Finding | Problema detectado por una regla (vulnerabilidad, defecto de arquitectura, etc.) |
| Pattern | Expresión regular o texto plano buscado en el código |
| Scope | Alcance de la búsqueda: línea, bloque de N líneas o archivo entero |
| Source | Entrada de datos no confiables (petición HTTP, entrada de teclado, etc.) |
| Sink | Función peligrosa donde los datos no confiables no deben llegar sin validación |
| Sanitizer | Función que neutraliza los datos peligrosos (escapado, validación, conversión) |
| Taint | Marcado de los datos como "contaminados" para seguir su propagación en el código |
| CWE | Common Weakness Enumeration — catálogo de debilidades de software |
| OWASP | Open Web Application Security Project — Top 10 de los riesgos de seguridad web |
| ASVS | Application Security Verification Standard — niveles de verificación de seguridad |
| ISO 27001 | Norma internacional de gestión de la seguridad de la información |
| SAST | Static Application Security Testing — análisis de seguridad sin ejecutar el código |
StaticCodeAudit — CodeFixture | Documentación DSL v1.0