DSL .sca Reference — StaticCodeAudit by CodeFixture
This document describes the complete syntax of .sca rule files. Each file defines a self-contained detection rule.
1. Rule structure
A .sca file contains a single rule. Minimal structure:
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 must be lowercase with underscores only: [a-z0-9_]+2. Rule keywords
| Keyword | Values | Required | Description |
|---|---|---|---|
language | python, javascript, java, csharp, php, html, yaml, dockerfile | required | Language of the analyzed code |
severity | CRITICAL, HIGH, MEDIUM, LOW, INFO | required | Finding severity |
category | security, arch, ui, ux, maintenance, cicd | optional | Category (default: security) |
confidence | 0 to 100 | optional | Confidence in % (default: 80) |
3. match block (pattern detection)
The match block defines the patterns to detect in the code. Repeatable (multiple blocks = OR).
3.1 match block keywords
| Keyword | Type | Description |
|---|---|---|
pattern | Regex | Regular expression to search for |
text | Plain text | Text escaped automatically. * = wildcard (anything) |
with | Regex | The context must also contain this pattern |
with-text | Plain text | Like with but escaped automatically |
pattern-not | Regex | The context must not contain this pattern |
text-not | Plain text | Like pattern-not but escaped |
scope | Value | Search scope (see below) |
3.2 Scopes
| Scope | pattern behavior | pattern-not behavior |
|---|---|---|
line | Checked line by line | Checked on the same line |
context-N | Checked over windows of N lines | Checked over the entire N-line block |
file | Checked over the entire file | Checked over the entire file |
3.3 text vs pattern
text — for all developers. The tool automatically escapes special characters. The * means "anything".
match
text .execute(
with-text f"*"
scope context-4
end
pattern — for regex experts. The pattern is used as-is.
match
pattern \.execute\s*\(.*f["']
scope context-4
end
Both examples above detect the same code.
4. requires block (file conditions)
The requires block defines conditions on the file. If used alone (without match), the finding is at file level (line 1). If combined with match, it serves as a pre-filter.
| Keyword | Logic | Description | Example |
|---|---|---|---|
has | ALL must match | The file content must contain this pattern | has @app\.route |
not_has | NONE may match | The file content must NOT contain this pattern | not_has logging |
min_lines | ≥ N | The file must have at least N lines | min_lines 500 |
path_contains | AT LEAST ONE must match | The file path must contain this segment | path_contains vendor/ |
not_path_has_file | NONE may exist | The file's directory must NOT contain this file | not_path_has_file LICENSE |
has, not_has, path_contains and not_path_has_file are repeatable (multiple lines = multiple conditions).Examples
# Flask file without logging
requires
has @app\.route
not_has import\s+logging
end
# File too long
requires
min_lines 500
end
# Vendor code without LICENSE
requires
path_contains vendor/
not_path_has_file LICENSE
not_path_has_file LICENSE.md
end
5. Taint analysis (source → sink)
Taint analysis traces the flow of data from sources (user inputs) to sinks (dangerous functions), unless a sanitizer intervenes.
| Keyword | Syntax | Description |
|---|---|---|
source | source <regex> kind=<type> | Origin of untrusted data |
sink | sink <regex> | Dangerous function receiving the data |
sanitizer | sanitizer <regex> | Function that neutralizes the data |
Source types (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. i18n blocks (risk, solution, message)
The risk, solution, benefit and message blocks support translation in 4 languages:
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. The report uses the language configured via --lang.7. metadata block (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
| Key | Format | Description |
|---|---|---|
cwe | CWE-NNN (multi) | Common Weakness Enumeration. Multiple values via repeated lines or space-separated tokens. |
cve | CVE-YYYY-NNNN (multi) | Specific CVE the rule was created for. Renders as a clickable link to NVD. |
owasp | ANN:YYYY | OWASP Top 10 |
iso27001 | A.N.NN (multi) | ISO/IEC 27001:2022 Annex A |
asvs | N.N.N (multi) | OWASP ASVS |
wcag | N.N.N (multi) | W3C WCAG 2.1 success criterion (used by accessibility rules instead of CWE). |
All multi-valued keys (cwe, cve,
iso27001, asvs, wcag) accept either
several tokens on a single line (cwe CWE-89 CWE-90)
or repeated lines — both are accumulated.
The metadata classification is propagated to all exports:
HTML (clickable links), JSON (finding.compliance object),
and SARIF (rule.properties.tags).
8. Execution modes
The mode is inferred automatically from the blocks present:
| Blocks present | Inferred mode |
|---|---|
match (pattern/text) | regex |
requires alone (has/not_has/min_lines) | file_contains |
match + requires | regex with file pre-filter |
source + sink | taint |
source + sink + match | regex+taint |
hook | python_hook (advanced custom rules) |
mode explicitly — automatic inference is recommended.9. Complete examples
9.1 Simple detection (plain text)
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 with exclusion (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 File condition only
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 Combo 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 Taint analysis (SQL injection)
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 Vendor governance check
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. Glossary
| Term | Definition |
|---|---|
| DSL | Domain-Specific Language — a language dedicated to defining audit rules |
| Finding | An issue detected by a rule (vulnerability, architectural flaw, etc.) |
| Pattern | Regular expression or plain text searched for in the code |
| Scope | Search scope: line, block of N lines, or entire file |
| Source | Untrusted data input (HTTP request, keyboard input, etc.) |
| Sink | Dangerous function where untrusted data must not arrive without validation |
| Sanitizer | Function that neutralizes dangerous data (escaping, validation, conversion) |
| Taint | Marking of data as "tainted" to track its propagation through the code |
| CWE | Common Weakness Enumeration — catalogue of software weaknesses |
| OWASP | Open Web Application Security Project — Top 10 web security risks |
| ASVS | Application Security Verification Standard — security verification levels |
| ISO 27001 | International standard for information security management |
| SAST | Static Application Security Testing — security analysis without executing the code |
StaticCodeAudit — CodeFixture | DSL Documentation v1.0