¿Es legal?
Solo con un mandato escrito de quien posee el sistema, que defina alcance, horarios y límites. Es lo primero que preparamos, y sin eso no se empieza: un test de intrusión no autorizado es un delito, para nosotros y para quien lo encarga.
Test de intrusión en web apps, portales y redes corporativas. No un escaneo automático con un sello al final: alguien que intenta entrar de verdad, con las mismas técnicas de quien lo haría para robar, y que después te escribe lo que ha encontrado en un lenguaje que puedes pasar a tu proveedor.
pentest --scope "app + api" --mode grey-box
superficie mapeada ..... 148 endpoints
intentos de acceso ..... ningún límite detectado
control de permisos .... 1 fallo crítico
[ok] informe entregado en 5 días laborables
pentest --retest
segunda pasada tras la corrección: incluida
esperando
$ ./infra --apri
Un bollino dice che avete chiuso a chiave. Non dice cosa c'è dentro, né chi ha ancora una copia delle chiavi. Scorri: si apre.
Cosa è raggiungibile da fuori, prima ancora di provare a entrare: domini, sottodomini, ambienti di prova rimasti accesi. Quasi sempre la lista vera è più lunga di quella che ci viene consegnata.
Il modulo di login, le sessioni, i limiti ai tentativi. Un accesso che non scade mai e una password senza freno sono due porte, non una.
Chi può leggere cosa, una volta dentro. È il punto in cui si trova più roba, ed è anche quello che le scansioni automatiche non sanno guardare.
Dove finiscono i dati quando nessuno li sta guardando: copie di sicurezza, esportazioni, allegati serviti senza controllo. Una copia dimenticata su un indirizzo pubblico vale un'intrusione riuscita.
I componenti di terzi che il software si porta dietro, e le versioni ferme da mesi. Il codice che non avete scritto voi è comunque codice vostro.
L'ultima domanda non è se qualcuno entra: è quanto ci mettete ad accorgervene. Registri, avvisi, e qualcuno che li legga davvero.
// cuándo hace falta
No le hace falta a todo el mundo por igual. Pero si reconoces tres, el coste de no mirar ya ha superado al de una prueba.
// qué hacemos de verdad
Un test serio se distingue de uno falso en una sola cosa: el falso produce una lista de avisos automáticos, este produce un camino recorrido.
Se mapea la superficie expuesta: dominios, subdominios, endpoints, servicios olvidados encendidos desde hace años. La mitad de las intrusiones empieza por algo que nadie sabía que seguía en línea.
Se prueban de verdad los caminos: permisos que se pueden esquivar, sesiones reutilizables, datos de otros accesibles cambiando un número. Acordamos antes los límites y los horarios, y nunca tocamos datos reales.
Una parte para quien decide — qué riesgo hay, cuánto es grave, qué hacer primero. Una parte para quien corrige, con peticiones, respuestas y pasos para reproducirlo. Sin la segunda, la primera no se puede arreglar.
Después de que hayáis corregido, volvemos a los mismos puntos y comprobamos. Es la parte que casi nadie incluye, y la única que demuestra que el problema está cerrado de verdad.
// cómo llegamos
Un test de intrusión sin un mandato firmado no es un test: es un delito. Es lo primero que ponemos sobre la mesa, y si falta no se empieza.
Se escribe qué está dentro y qué fuera, en qué horarios, con qué límites. Firmado por quien tiene poder para autorizarlo — no por quien gestiona el sistema, por quien lo posee.
Se construye el inventario de lo que es accesible. A menudo es aquí donde sale la primera sorpresa: un entorno de pruebas abierto, un subdominio viejo todavía vivo.
Los fallos críticos se comunican al momento, no en la entrega: si encontramos una puerta abierta a los datos de vuestros clientes, lo sabéis ese mismo día.
Entrega del informe con prioridades y pasos de corrección, y después de vuestras intervenciones volvemos a comprobar los mismos puntos.
$ ./pentest --target "tu sistema"
In ordine di gravità, come nel referto vero. La prima riga non è la più facile da correggere: è quella che costa di più se resta dov'è.
Cambiando un número en la dirección se abrían los documentos de otra empresa. Es el fallo más común que encontramos, y casi nunca nadie lo ha buscado.
Claves de API y contraseñas dentro del repositorio o dentro del JavaScript que llega al navegador. Cualquiera que sepa mirar, las encuentra.
El formulario de acceso aceptaba intentos infinitos: una contraseña débil cae en pocos minutos.
Un acceso robado sigue valiendo para siempre. Quien dejó la empresa todavía entra.
Componentes con vulnerabilidades conocidas y ya publicadas. No hace falta un ataque: basta leer el boletín.
Ninguna de estas es teórica: son las cinco que encontramos más a menudo. El informe que entregamos dice dónde está, cómo llegamos y qué hacer — con la reprueba gratuita después de la corrección.
// un fragmento de informe
Esta es la forma en que llegan las cosas al informe: qué hemos enviado, qué ha respondido y dónde está el problema. Es también el fallo que encontramos con más frecuencia.
informe 04 · falta el control de autorización · gravedad alta
# La sesión es la de un usuario real: ha iniciado sesión\n# con normalidad. Solo cambia el número de la dirección.\n\nGET /api/documenti/4187 HTTP/2\nHost: portale.esempio.it\nCookie: sessione=8f2a91c4d7e0\n\nHTTP/2 200 OK\nContent-Type: application/json\n\n{\n "id": 4187,\n "cliente": "otra empresa",\n "file": "contratto-firmato.pdf",\n "url": "https://portale.esempio.it/media/9f1c2b.pdf"\n}
// El código que respondió 200.\n\nfunction documento(int $id): ?array\n{\n // Hay un control y, a primera vista, es el correcto:\n // sin sesión válida de aquí no se pasa.\n if (!utente_autenticato()) {\n return null;\n }\n\n // Pero la pregunta que responde esta línea es\n // "¿existe el documento 4187?" — y no\n // "¿el documento 4187 es de quien lo está pidiendo?".\n return db()->riga(\n 'SELECT * FROM documenti WHERE id = ?',\n [$id]\n );\n}
// La misma función, con el propietario dentro de la pregunta.\n\nfunction documento(int $id): ?array\n{\n $utente = utente_autenticato();\n if (!$utente) {\n return null;\n }\n\n // Ahora la línea pregunta las dos cosas a la vez, y\n // el documento de otro no está "prohibido": no existe.\n // Ningún segundo control que recordar en otro sitio, porque\n // no queda ningún otro sitio donde olvidarlo.\n return db()->riga(\n 'SELECT * FROM documenti WHERE id = ? AND cliente_id = ?',\n [$id, $utente->cliente_id]\n );\n}
La corrección no añade un control: elimina la posibilidad de olvidarlo. Mientras la autorización sea un if escrito junto a la consulta, tarde o temprano alguien escribirá una consulta nueva sin ese if al lado. Metida dentro de la consulta, la pregunta equivocada ya no se puede formular — y quien prueba un número al azar recibe un 404, así que ni siquiera aprende que ese número corresponde a algo.
$ cat stack.json
$ ./domande --frequenti
Solo con un mandato escrito de quien posee el sistema, que defina alcance, horarios y límites. Es lo primero que preparamos, y sin eso no se empieza: un test de intrusión no autorizado es un delito, para nosotros y para quien lo encarga.
Las pruebas destructivas — las que pueden tirar un servicio — solo se hacen si se piden y en entornos acordados, con una ventana declarada. En sistemas en producción trabajamos de forma no destructiva y no tocamos datos reales.
Un test sobre una web app de tamaño medio lleva entre 5 y 10 días laborables, informe incluido. El reconocimiento lleva más tiempo del que se imagina: es la parte que decide la calidad de todo lo demás.
Un informe en dos partes: una para quien decide, con riesgo y prioridades, y una técnica con pasos para reproducir cada fallo. Más una llamada para leerlo juntos, porque un PDF entregado y ya acaba en una carpeta.
Si recoge datos de personas, sí — y no por el tamaño: los escaneos automáticos que buscan fallos no miran la facturación. Si es una web corporativa sin datos y sin área privada, a menudo la respuesta honesta es que bastan actualizaciones y copias de seguridad.
La seguridad no es un estado sino un mantenimiento: actualizaciones, revisión de accesos, y una prueba nueva cuando cambia algo relevante. En el informe escribimos cada cuánto tiene sentido repetirlo en vuestro caso.
fymera init --proyecto "el tuyo"
Treinta minutos por vídeo para entender el alcance. Si la respuesta correcta es «actualizad y poned un límite a los intentos de acceso», os lo decimos sin venderos un test.