saltar al contenido
volver al mapa
técnica
etapa: ship
3 min de lectura

A08 Software or Data Integrity Failures

Si el programa acepta actualizaciones, plugins, objetos serializados o la salida de un pipeline sin probar de dónde vienen, quien pueda alterarlos puede ejecutar código como tú.

Sigstore cosignSLSA provenanceSubresource Integrity (SRI)ysoserial (to understand the risk, on your own lab)Semgrepin-toto

Qué es

Las fallas de integridad ocurren cuando se confía en código o datos sin verificarlos: actualizaciones automáticas sin firma, scripts cargados desde una CDN sin comprobación de integridad, deserialización de bytes no confiables y pipelines de CI/CD donde un solo paso comprometido puede alterar lo que se entrega.

El :2025 mantiene esta categoría como A08. Es cercana al A03 (cadena de suministro), pero se centra en el paso de verificación: ¿puedes demostrar que lo que ejecutas es lo que se pretendía ejecutar?

Cómo funciona el ataque

  • : la aplicación reconstruye objetos a partir de bytes suministrados por el atacante (serialización de Java, pickle de Python, YAML inseguro), y el stream provoca ejecución de código.
  • Actualización o plugin manipulado: una descarga por un canal sin firma se reemplaza en tránsito o en el mirror.
  • Script de terceros sin verificar: una CDN comprometida sirve JavaScript modificado a todos los visitantes.
  • Estado controlado por el cliente: una cookie o un campo oculto que lleva un rol, precio u objeto se edita y se acepta.

Código vulnerable

Deserializar bytes no confiables con pickle, confiar en una cookie editable por el usuario y cargar un script sin atributo de integridad.

session.pypython
import pickle, base64

def load_prefs(cookie):
    return pickle.loads(base64.b64decode(cookie))   # los bytes controlados por el atacante ejecutan código
cart.jsjavascript
const cart = JSON.parse(Buffer.from(req.cookies.cart, "base64").toString());
total = cart.total;          // el cliente escribió este número
index.htmlhtml
<script src="https://cdn.example.com/lib/chart.min.js"></script>

La corrección

Usa formatos solo de datos (JSON) con validación de esquema, nunca serialización nativa de objetos para entradas no confiables. Si el estado debe pasar por el cliente, fírmalo (HMAC o un token firmado) y verifícalo antes de usarlo, o mejor, mantenlo en el servidor. Fija los scripts de terceros con y verifica las firmas de todo lo que instales o actualices.

session.pypython
import hmac, hashlib, json, base64

SECRET = load_secret("PREFS_HMAC_KEY")

def dump_prefs(prefs: dict) -> str:
    body = base64.urlsafe_b64encode(json.dumps(prefs).encode())
    mac = hmac.new(SECRET, body, hashlib.sha256).hexdigest().encode()
    return (body + b"." + mac).decode()

def load_prefs(cookie: str) -> dict:
    body, _, mac = cookie.encode().partition(b".")
    expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest().encode()
    if not hmac.compare_digest(mac, expected):
        raise ValueError("tampered")
    return json.loads(base64.urlsafe_b64decode(body))      # solo datos, validados después
cart.jsjavascript
// el estado vive en el servidor; la cookie solo lleva un id opaco
const cart = await carts.get(req.session.cartId);
const total = cart.items.reduce((s, i) => s + catalog.price(i.sku) * i.qty, 0);
index.htmlhtml
<script src="https://cdn.example.com/lib/chart-4.4.1.min.js"
        integrity="sha384-<hash of the exact file>"
        crossorigin="anonymous"></script>
verifica antes de ejecutarbash
# el artefacto debe estar firmado por la identidad de pipeline esperada
cosign verify-blob --certificate-identity 'https://github.com/example/app/.github/workflows/release.yml@refs/heads/main' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --signature app.tgz.sig --certificate app.tgz.pem app.tgz

Demuestra la corrección

Alimenta el código exactamente con lo que haría un atacante: una cookie modificada, un payload de un gadget de deserialización y un archivo de script alterado. El resultado correcto es el rechazo, sin ejecutar ningún código.

test_integrity.py (pytest)python
def test_tampered_cookie_is_rejected():
    cookie = dump_prefs({"theme": "dark"})
    body, mac = cookie.split(".")
    forged = base64.urlsafe_b64encode(b'{"theme":"dark","role":"admin"}').decode() + "." + mac
    with pytest.raises(ValueError):
        load_prefs(forged)

def test_pickle_payload_is_not_executed(tmp_path):
    marker = tmp_path / "pwned"
    class Evil:
        def __reduce__(self):
            return (open, (str(marker), "w"))
    payload = base64.b64encode(pickle.dumps(Evil())).decode()
    with pytest.raises(Exception):
        load_prefs(payload)
    assert not marker.exists()
sri-check.shbash
# todo <script> y <link rel=stylesheet> externo debe llevar un atributo integrity
! grep -RInE '<script[^>]+src="https?://' dist/ | grep -v 'integrity='

Checklist

  • Nunca deserialices datos no confiables con un formato capaz de instanciar objetos; prefiere JSON con validación de esquema.
  • Firma todo lo que deba cruzar una (cookies, archivos de actualización, mensajes) y verifica antes de usar.
  • Usa Subresource Integrity para scripts y estilos de terceros, o alójalos tú mismo.
  • Firma los artefactos de build y las imágenes de contenedor; verifica la firma en el momento del deploy.
  • Protege el pipeline: cambios revisados, permisos de build y deploy separados, ningún código sin revisar en los pasos de release.
  • Prefiere el estado del lado del servidor para precios, roles y permisos.
OWASP Top 10La lista de referencia más conocida de riesgos de seguridad en aplicaciones web (A01 control de acceso roto, A02 fallas criptográficas, A03 inyección...), revisada cada pocos años por la comunidad OWASP. Es un mapa educativo de categorías de riesgo, no un checklist de herramientas ni una certificación.ver en el glosario →Deserialización inseguraReconstruir objetos a partir de bytes no confiables con un formato que puede instanciar tipos arbitrarios (serialización de Java, pickle). Los bytes pueden provocar la ejecución de código.ver en el glosario →Subresource IntegritySRIUn hash en una etiqueta script o link que hace que el navegador rechace el archivo si no coincide, de modo que una CDN comprometida no pueda alterar tu página.ver en el glosario →Frontera de confianzatrust boundaryLínea donde cambia el nivel de confianza de los datos o de quien los envía (internet a VPC, servicio a base de datos, usuario a admin). Todo lo que la cruza debe ser autenticado, autorizado y validado.ver en el glosario →

conexiones en el mapa

actualizado el 14/10/2026 · fuentes para profundizar · reportar un error

en otros dominios

Estudia antes

pon a prueba lo que entendiste

Cargando preguntas…