# Audita el JavaScript de un sitio en producción

Escanea una URL en producción en busca de source maps públicos, código legible y credenciales filtradas, y obtén una puntuación sobre 100. El mismo escáner que impulsa el escáner de seguridad público, desde tu terminal.

Source: https://www.afterpack.dev/es/docs/audit

`npx afterpack@latest audit <url>` descarga el JavaScript que sirve un sitio e informa de lo que un lector puede sacar de él. Es el mismo escáner que impulsa el [escáner de seguridad](https://www.afterpack.dev/es/security-scanner) público: source maps públicos, qué tan legible es tu propio código, credenciales filtradas y, sin puntuar, código de terceros, sinks de código dinámico y el stack detectado.

Audit es de solo lectura. No modifica nada, no necesita [cuenta](https://www.afterpack.dev/es/docs/accounts) y solo accede a lo que la URL sirve públicamente.

> **Una herramienta distinta del motor de ofuscación**
>
> `audit` no ejecuta [el motor de ofuscación](https://www.afterpack.dev/es/docs/concepts). Descarga los recursos que sirve un sitio y analiza lo que ya está expuesto. Ninguno de los [flags de build](https://www.afterpack.dev/es/docs/cli#flags) se aplica a él.

## Ejecútalo

```bash
npx afterpack@latest audit https://yoursite.com
```

El esquema es opcional: un nombre de host sin más se normaliza a `https://`. El escáner descarga la página, la renderiza para incluir los bundles que se cargan en el cliente y después analiza cada recurso JavaScript que encontró.

> **Solo URL en producción**
>
> No hay modo de directorio local. `npx afterpack@latest audit ./dist` no está soportado. El argumento debe ser una URL. En su lugar, audita un despliegue de preview.

## Qué comprueba

| Comprobación | Qué encuentra |
| --- | --- |
| **Source maps públicos** | Un archivo `.map` junto a cualquiera de tus scripts más grandes, encontrado por cabecera, comentario o petición directa, y si incluye tu código original. Un map con código limita la puntuación a 10; uno solo con mappings, a 50. Un directorio `.git` público cuenta igual que un map con código. |
| **Código legible** | Para cada uno de tus scripts, cuánto recupera un lector como código normal: cadenas en inglés, nombres con significado y acceso a propiedades, medido sobre los tokens. Cada archivo se califica como sin procesar, minificado u ofuscado. Vale 75 puntos, ponderados por bytes. La versión token a token de esta pregunta es el [Protection Map](https://www.afterpack.dev/es/docs/protection-map). |
| **Credenciales filtradas** | Claves privadas, secretos de la nube, secretos de pagos, tokens de repositorios y de chat, URLs de bases de datos y tokens bearer, enmascarados y con su contexto. Vale 25 puntos. Los emails, las direcciones IP y las claves públicas de navegador se listan sin puntuar. |
| **Código de terceros** | SDKs de terceros servidos desde el sitio, identificados por host, ruta o cabecera de licencia. Se listan aparte y no cuentan para la puntuación. |
| **Higiene** | `eval()`, el constructor `Function`, `document.write` y sinks de HTML sin escapar, dominios de terceros y el stack detectado. Se listan sin puntuar. |

### Source maps expuestos

Un source map enlaza tu bundle publicado con tu código fuente original y legible. Nunca publiques uno en producción: un atacante lo descarga y lee tu código tal como lo escribiste.

Audit lo detecta. Un build de [producción](https://www.afterpack.dev/es/docs/config#build-mode) con AfterPack no escribe ningún `.map` y elimina los que escribió tu bundler (consulta [`sourceMap.enabled`](https://www.afterpack.dev/es/docs/config#sourceMap-enabled) y [`sourceMap.emitUrl`](https://www.afterpack.dev/es/docs/config#sourceMap-emitUrl)), pero un mapa que tu despliegue copia desde otro lugar se sigue publicando.

## Leer los resultados

La CLI imprime cada fase a medida que termina, muestra en línea los hallazgos `critical` y `high` según llegan y cierra con un recuadro de resumen: puntuación sobre 100, recuento de scripts, hallazgos por severidad y stack detectado. Termina con una lista de todos los hallazgos críticos y un enlace al informe completo en la web.

Léelo de arriba abajo:

1. **Primero, los source maps.** Un map público entrega a cualquiera tu código tal como lo escribiste, haga lo que haga el build. Elimina todos los `.map` de producción.
2. **Después, las credenciales.** Rota cualquier credencial filtrada y deja de publicarla.
3. **Por último, el código legible.** Si tus propios archivos salen sin procesar o minificados, no tienen ninguna protección significativa. Pasa un build por AfterPack (el [Quickstart](https://www.afterpack.dev/es/docs/quickstart) lleva unos cinco minutos).

Por defecto, la salida es texto legible por humanos. `--diagnostics.format=json` pone en su lugar un único documento JSON en stdout (los hallazgos, la puntuación y el enlace al informe) y mueve cada línea legible por humanos a stderr; `--diagnostics.level=none` silencia además las fases de progreso. El informe que se puede compartir es siempre el enlace web con el que termina la ejecución.

### Sin calificar

Un escaneo no recibe puntuación cuando la página no tiene código propio del sitio o cuando el escáner no pudo leerlo. El informe dice **Sin calificar** en lugar de un número, y explica por qué:

- **Sin JavaScript propio.** La página no carga ningún script del propio sitio, así que no hay nada que calificar. Escanea una página que cargue la aplicación, como una página de producto.
- **Bloqueado.** El sitio respondió al escáner con una verificación antibots o una página de error en lugar de la página.
- **Scripts sin leer.** La página carga sus propios scripts, pero el escáner no pudo leer la mayoría. Vuelve a escanear.

Un escaneo bloqueado, o uno cuyos scripts no se leyeron, nunca se reutiliza en la ventana de repetición de 30 minutos, así que un escaneo nuevo se ejecuta enseguida. Cuando solo faltan unos pocos scripts, el escaneo se califica con los que leyó y el informe dice cuántos se le escaparon.

## Códigos de salida

| Código | Cuándo |
|---|---|
| `0` | El escaneo se completó. **Incluso cuando encontró problemas críticos.** |
| `1` | El escaneo falló: una URL inaccesible, un error del lado del servidor, el límite diario de peticiones o un stream que terminó sin completarse. |
| `64` | Uso incorrecto: no se dio ninguna URL, se dio más de una o la URL está mal formada. |

Estos son los códigos propios de audit. Los [códigos de salida del build](https://www.afterpack.dev/es/docs/diagnostics#exit-codes) que usa una ejecución de ofuscación son distintos.

> **Audit no es una puerta de CI**
>
> Como un escaneo completado sale con `0` independientemente de lo que encontró, `npx afterpack@latest audit … && deploy` no falla ante los hallazgos. No hay ningún flag de umbral de severidad: lee tú mismo los hallazgos desde `--diagnostics.format=json` si quieres bloquear en función de ellos. Usa audit como un paso de revisión previo al lanzamiento que lees manualmente. La ejecución de ofuscación es [la parte que hace fallar un build](https://www.afterpack.dev/es/docs/builds).

Los escaneos sin autenticar están limitados a **3 por IP cada 24 horas**, y un mismo sitio se puede escanear 10 veces por hora. Al alcanzar un límite, se imprime cuánto hay que esperar y se sale con `1`. Repetir el escaneo de la misma URL en menos de 30 minutos devuelve el informe existente y no cuenta para el límite.

## La insignia de AfterPack

Pon la insignia en el pie de página o el README de tu sitio. Dice **Protected by AfterPack** mientras el último escaneo de tu host encuentre salida de AfterPack en el código propio del sitio, sin source maps ni credenciales públicas, y nota A. Si no, muestra la última puntuación, o **not graded** mientras ningún escaneo de tu host [haya calificado el sitio](#not-graded). Un host que nunca se escaneó muestra **Scan with AfterPack**. La insignia enlaza al último informe y se actualiza en menos de una hora tras un escaneo nuevo.

![AfterPack badge](https://www.afterpack.dev/badge/www.afterpack.dev.svg?style=wide)

Pie de página:

```html
<a href="https://www.afterpack.dev/security-scanner/site/yoursite.com?ref=badge" rel="noopener" title="AfterPack security scan">
  <img src="https://www.afterpack.dev/badge/yoursite.com.svg?style=compact&theme=dark" alt="AfterPack badge" width="200" height="32" loading="lazy">
</a>
```

README:

```markdown
[![AfterPack badge](https://www.afterpack.dev/badge/yoursite.com.svg)](https://www.afterpack.dev/security-scanner/site/yoursite.com?ref=badge)
```

Estilos: `compact` (200×32) y `wide` (236×48) para pies de página, `flat` (20 px) para READMEs. Temas: `dark` y `light`. Cada página de resultados del [escáner de seguridad](https://www.afterpack.dev/es/security-scanner) tiene estos fragmentos para su host.

## Siguiente

- [Builds y CI](https://www.afterpack.dev/es/docs/builds): integrar la ofuscación en tu pipeline de publicación y fijar una semilla para obtener una salida reproducible.
- [Buenas prácticas](https://www.afterpack.dev/es/docs/best-practices): qué marcar, qué dejar sin tocar y la regla de los source maps.
- [Escáner de seguridad](https://www.afterpack.dev/es/security-scanner): las mismas comprobaciones en tu navegador, sin instalar nada, con el informe completo para compartir.
- [Protection Map](https://www.afterpack.dev/es/docs/protection-map): la vista token a token de tu propio build, una vez que ofusques.
- [Qué no reemplaza AfterPack](https://www.afterpack.dev/es/docs/threat-model#what-afterpack-does-not-replace): un secreto filtrado necesita rotarse; ofuscarlo a posteriori no sirve de nada.
