Un cheque perdido que podría costarle caro: Requests.get y el formulario de solicitud de Flask
Imagínate esto: un desarrollador junior trabaja bajo presión para lanzar una función. Abre una aplicación Flask, añade una nueva ruta, obtiene un parámetro de consulta y continúa.
# Demonstrative example only — NOT executable, not exploitable
from flask import Flask, request
@app.route("/items")
def get_items():
# Type casting avoids unsafe string injection
item_id = request.args.get("id", type=int)
# Safe usage: forces integer input, prevents injection
A primera vista, el uso de esta solicitud de Flask parece correcto. Pero omítalo. tipo=int y abres la puerta a ataques de inyección. Estos son los tipos de riesgos que pasan inadvertidos en las revisiones de código porque “solo se trata de obtener un valor”.
Dónde se esconde el riesgo FSolicitud de lask y FFormulario de solicitud de lask
Ambos solicitud de matraz y formulario de solicitud de matraz Son puntos de entrada no confiables. Todo valor que devuelven proviene directamente del cliente y debe considerarse potencialmente hostil.
No validar o desinfectar estos datos puede generar problemas de seguridad críticos, incluidos:
- inyección SQL
- Secuencias de comandos entre sitios (XSS)
- Inyección de plantilla
- Inyección de comandos de shell
Estos riesgos no sólo se aplican a las bases de datos o a la renderización front-end; los atacantes también pueden explotar las entradas utilizadas en plantillas o pasadas a subprocesos.
Patrones de pseudocódigo seguros:
python
# ⚠️ Educational example only — not functional
env_target = input("Enter deployment environment: ")
simulate_deploy(env_target) # Simulated for demonstration
Preventivo CI/CD aplicación:
# 1. Query parameter — Safe with casting
user_id = request.args.get("id", type=int) # Enforces integer type
# 2. Form parameter — Safe with casting
username = request.form.get("username", type=str) # Enforces string type
# 3. Template rendering safeguard
template_data = {"name": request.args.get("name", type=str)} # Avoids untrusted HTML injection
# 4. Shell command safe handling
filename = request.args.get("file", type=str)
# Validate filename against known safe values before use in subprocess (not shown)
Incluso si la sintaxis parece segura, usar valores sin procesar o sin verificar en plantillas o comandos del sistema puede convertirse en un vector de inyección serio.
Flujo de inyección práctico (simulación segura)
Así es como normalmente se desarrolla una falla de inyección, utilizando un escenario ficticio y seguro:
- Un usuario envía un parámetro de consulta elaborado a la aplicación.
- La aplicación lee el valor usando solicitud.args.get() sin validación.
- Ese valor se concatena directamente en una consulta SQL, una cadena de plantilla o un comando de shell.
- El sistema ejecuta esa lógica sin darse cuenta del contenido inyectado.
Pseudocódigo (inseguro, sólo ilustrativo):
# Insecure example — do not run in production
user_id = request.args.get("id") # Missing type casting, no validation
query = f"SELECT * FROM users WHERE id = {user_id}" # Risk of injection
Rastro de registro ficticio:
[INFO] Incoming request: /user?id=unexpected_input
[DEBUG] Parsed user_id: unexpected_input
[DEBUG] Constructed SQL: SELECT * FROM users WHERE id = unexpected_input
Si bien este ejemplo utiliza marcadores de posición, refleja cómo pequeños descuidos en el manejo de entradas pueden generar vulnerabilidades críticas.
Las pruebas automatizadas pueden pasar por alto esto porque generalmente prueban tipos de entrada válidos, no aquellos maliciosos o maliciosos.
Riesgos ocultos en el uso de dependencias Solicitud de matraz y Formulario de solicitud de matraz
Puede que su código esté limpio, pero los paquetes de terceros aún pueden causarle problemas.
Algunos complementos o bibliotecas de Flask llaman internamente a la solicitud de Flask o al formulario de solicitud de Flask sin validación.
Ejemplo con paquetes ficticios:
python
# Insecure example — do not run in production
return AutoFormHandler.process() # May use request.form.get() without validation
python
# Insecure example — do not run in production
query = build_query(request.args) # May use request.args.get() without casting
In CI/CDLas actualizaciones de dependencia automatizadas pueden introducir silenciosamente llamadas request.get inseguras o patrones de manejo de entrada vulnerables.
Qué tan inseguro Solicitud de matraz El uso supera las revisiones de código
En entornos de ritmo rápido, errores pequeños pero peligrosos a menudo pasan desapercibidos, especialmente cuando el cambio parece inofensivo.
Ejemplo pull request diferencia:
# Insecure example — do not run in production
- user_id = request.args.get("id")
+ user_id = request.args.get("id") # Still missing type casting
Comentario del revisor:
"Se ve bien, solo está obteniendo un parámetro".
Este tipo de descuido es común debido a:
- Sesgo cognitivo:Los revisores pueden asumir que request.args.get() es seguro de forma predeterminada.
- La presión del tiempoLos controles de seguridad pasan a un segundo plano cuando se acercan los plazos.
- Familiaridad con Diff:El cambio parece menor, por lo que no se examina en profundidad.
Sin reglas claras ni una aplicación automatizada, estos riesgos sutiles pasan desapercibidos en la producción.
Prevención que funciona
Para mitigar los riesgos de inyección, combine la validación de entrada, el escaneo automatizado y la cobertura de pruebas.
Validación de entrada con conversión y lista blanca:
user_id = request.args.get("id", type=int)
if user_id not in [1, 2, 3]:
abort(400, "Invalid ID")
La conversión fuerza el valor a un tipo seguro, mientras que la inclusión en la lista blanca garantiza que solo se proceda con valores conocidos como correctos.
Pruebas de seguridad de aplicaciones estáticas (SAST) en CI/CD:
name: Run SAST scan
run: sast-tool --scan src/ --fail-on "request.args.get without type"
Este paso ayuda a detectar errores no validados. solicitud.args.get() or solicitud.formulario.obtener() llamadas antes de que lleguen a producción.
Pruebas unitarias para reforzar la desinfección:
def test_invalid_type(client):
response = client.get("/items?id=abc")
assert response.status_code == 400
These tests ensure the app rejects malformed or malicious input consistently.
Integrating Into DevSecOps Pipelines
Middleware enforcement:
@app.before_request
Estas pruebas garantizan que la aplicación rechace sistemáticamente entradas maliciosas o malformadas.
Integración en DevSecOps Pipelines
Aplicación de middleware:
@app.antes_de_la_solicitud
def sanitize_input():
if "id" in request.args and not request.args.get("id", type=int):
abort(400, "Invalid ID")
Pre-commit hook:
bash
if grep -R "request.args.get(" . | grep -v "type="; then
echo "Unsafe request.args.get detected — please add type casting."
exit 1
fi
Escaneando tanto su código como las dependencias de terceros ayuda a detectar solicitudes no seguras.get, solicitudes flask y el uso del formulario de solicitud flask antes de que lleguen a producción.
Este problema va más allá del matraz
El manejo inseguro de entradas no es exclusivo de Flask, sino que existe en todos los frameworks web. Afortunadamente, la solución es consistente: validar las entradas de forma temprana y rigurosa.
Django (pseudocódigo seguro):
# Enforces integer type and applies whitelist
user_id = int(request.GET.get("id", "0"))
if user_id not in [1, 2, 3]:
return HttpResponseBadRequest()
FastAPI (seguro por diseño utilizando sugerencias de tipo):
from fastapi import Query
@app.get("/items")
def read_items(id: int = Query(..., ge=1, le=3)):
return {"id": id}
Ambos ejemplos refuerzan el tipo y el rango de entrada, lo que garantiza que los datos entrantes sean confiables antes de que lleguen a la lógica sensible.
Ya sea Flask, Django o FastAPI, cada parámetro de solicitud es un punto de inyección potencial si no se valida correctamente.
Uso de Xygeni para la detección en DevSecOps
En un entorno DevSecOps, las revisiones manuales no son suficientes. xygeni Automatiza la detección de solicitudes de matraz inseguras, formularios de solicitud de matraz y el uso de requests.get.
Aplicaciones prácticas de DevSecOps:
- Escaneos estáticos: Marca cualquier solicitud.args.get() sin tipo =, y las llamadas al formulario de solicitud de flask carecen de validación.
- Análisis de dependencia:Supervisa las bibliotecas en busca de patrones inseguros que podrían surgir a través de llamadas indirectas.
- Bloqueo de fusiones inseguras: CI/CD falla si el nuevo código introduce solicitudes riesgosas o acceso a formularios no validados.
- Cumplimiento de la línea base:Realiza un seguimiento de los cambios para evitar que las llamadas seguras se conviertan en inseguras.
La automatización de estos controles reduce el riesgo de error humano y Mantiene la seguridad continua sin ralentizar la entrega.
Entonces, validar, desinfectar, automatizar
En resumen: requests.get, flask request y flask request form son todos no confiable por defectoCon gusto le entregarán datos maliciosos a menos que usted tome medidas.
Tus tres reglas:
- Validar Entradas mediante casting y listas blancas.
- Desinfectar antes de que los datos entren en contacto con operaciones sensibles.
- Automatiza los procesos con tecnología. cheques en tu pipeline para detener el código inseguro antes de la implementación.
Un solo controlador de solicitudes de Flask inseguro, un campo de formulario de solicitud de Flask sin verificar o una llamada a requests.get sin protección pueden comprometer su aplicación. Trate cada parámetro como potencialmente hostil y deje que su equipo de DevSecOps... pipeline Hacer cumplir las reglas en todo momento.





