Saltar al contenido principal

Reglas por lenguaje

Colección de reglas personalizadas organizadas por lenguaje, listas para copiar a tu proyecto.

Python

Inyección SQL (Django ORM)

rules:
- id: django-raw-sql
patterns:
- pattern-either:
- pattern: RawSQL(...)
- pattern: $MODEL.objects.raw($QUERY, ...)
- pattern: connection.cursor().execute($QUERY, ...)
- pattern-not: $MODEL.objects.raw("...", [...])
message: >
Uso de SQL raw — verifica que los parámetros estén parametrizados
y no concatenados en el string.
languages: [python]
severity: ERROR
metadata:
cwe: "CWE-89"

Deserialización insegura

rules:
- id: unsafe-pickle
pattern-either:
- pattern: pickle.loads(...)
- pattern: pickle.load(...)
- pattern: cPickle.loads(...)
- pattern: cPickle.load(...)
message: >
pickle.load() ejecuta código arbitrario — nunca deserialices datos
de fuentes no confiables. Usa json o msgpack.
languages: [python]
severity: ERROR
metadata:
cwe: "CWE-502"

SSRF

rules:
- id: python-ssrf
patterns:
- pattern-either:
- pattern: requests.get($URL, ...)
- pattern: requests.post($URL, ...)
- pattern: urllib.request.urlopen($URL, ...)
- pattern: httpx.get($URL, ...)
- pattern-not: requests.get("...", ...)
- pattern-not: requests.post("...", ...)
- pattern-not: urllib.request.urlopen("...", ...)
- pattern-not: httpx.get("...", ...)
message: >
URL dinámica en petición HTTP — valida contra una allowlist
para prevenir SSRF.
languages: [python]
severity: WARNING
metadata:
cwe: "CWE-918"

Subprocess con shell=True

rules:
- id: subprocess-shell
pattern: subprocess.call(..., shell=True, ...)
fix: subprocess.call(..., shell=False, ...)
message: >
shell=True permite inyección de comandos — usa shell=False
y pasa argumentos como lista.
languages: [python]
severity: ERROR
metadata:
cwe: "CWE-78"

JavaScript / TypeScript

XSS con dangerouslySetInnerHTML

rules:
- id: react-dangerously-set-innerhtml
pattern: <$TAG dangerouslySetInnerHTML={...} />
message: >
dangerouslySetInnerHTML puede causar XSS — sanitiza el HTML
con DOMPurify antes de renderizar.
languages: [typescript, javascript]
severity: ERROR
metadata:
cwe: "CWE-79"

Prototype pollution

rules:
- id: prototype-pollution
patterns:
- pattern: $OBJ[$KEY] = $VAL
- pattern-inside: |
function $FUNC(..., $KEY, ...) {
...
}
message: >
Asignación dinámica de propiedad con clave controlada por usuario —
puede causar prototype pollution. Valida $KEY contra una allowlist.
languages: [javascript, typescript]
severity: WARNING
metadata:
cwe: "CWE-1321"

Regex denial of service (ReDoS)

rules:
- id: regex-dos
pattern-either:
- pattern: new RegExp($INPUT)
- pattern: new RegExp($INPUT, ...)
message: >
Regex construido con input de usuario — puede causar ReDoS.
Usa una librería segura como re2 o valida el patrón primero.
languages: [javascript, typescript]
severity: WARNING
metadata:
cwe: "CWE-1333"

eval / Function constructor

rules:
- id: js-code-injection
pattern-either:
- pattern: eval(...)
- pattern: new Function(...)
- pattern: setTimeout($CODE, ...)
- pattern: setInterval($CODE, ...)
message: >
Ejecución dinámica de código — evita eval() y Function().
Si es inevitable, nunca pases input de usuario.
languages: [javascript, typescript]
severity: ERROR
metadata:
cwe: "CWE-94"

Go

Inyección SQL

rules:
- id: go-sqli
patterns:
- pattern-either:
- pattern: $DB.Query(fmt.Sprintf("...", ...), ...)
- pattern: $DB.Exec(fmt.Sprintf("...", ...), ...)
- pattern: $DB.QueryRow(fmt.Sprintf("...", ...), ...)
- pattern: $DB.Query($Q + $V, ...)
- pattern-not: $DB.Query("...", ...)
message: >
SQL construido con concatenación/Sprintf — usa placeholders:
db.Query("SELECT * FROM users WHERE id = $1", id)
languages: [go]
severity: ERROR
metadata:
cwe: "CWE-89"

Path traversal

rules:
- id: go-path-traversal
patterns:
- pattern-either:
- pattern: os.Open(filepath.Join($BASE, $INPUT))
- pattern: os.ReadFile(filepath.Join($BASE, $INPUT))
- pattern: http.ServeFile($W, $R, $PATH)
- pattern-not-inside: |
if !strings.Contains($INPUT, "..") {
...
}
message: >
Posible path traversal — valida que el path resuelto
esté dentro del directorio esperado con filepath.Rel().
languages: [go]
severity: ERROR
metadata:
cwe: "CWE-22"

Crypto débil

rules:
- id: go-weak-crypto
pattern-either:
- pattern: md5.New()
- pattern: md5.Sum(...)
- pattern: sha1.New()
- pattern: sha1.Sum(...)
- pattern: des.NewCipher(...)
- pattern: rc4.NewCipher(...)
message: >
Algoritmo criptográfico débil — usa sha256, aes
u otros algoritmos modernos.
languages: [go]
severity: WARNING
metadata:
cwe: "CWE-327"

Uso

Guarda las reglas en un directorio semgrep-rules/ y ejecútalas:

# Todas las reglas locales
semgrep --config=semgrep-rules/ src/

# Reglas locales + registry
semgrep --config=semgrep-rules/ --config=p/ci src/

# Solo un archivo de reglas
semgrep --config=semgrep-rules/python.yaml src/

Referencias