Bug real en McDelivery India. PUT /cart/<id> se traga
cualquier campo del JSON (mass assignment), el backend firma con RSA el
orderDetails ya tocado por el cliente. Cualquiera con la pública dará la
firma por buena, sin saber que el total es mentira. Resultado: 30
hamburguesas a 1 rupia (~1 céntimo).
Writeup original: https://eaton-works.com/2024/12/19/mcdelivery-india-hack/
docker compose up --buildDos servicios:
- backend en
:5001. Flask + RSA. Genera el keypair RSA-2048 al arrancar. - frontend en
:8080. UI genérica (BurgerLab) servida por nginx.
UI en navegador: http://localhost:8080
El frontend es una UI inventada (BurgerLab) sin relación con ninguna marca real. Solo está para ver el ataque visualmente.
./exploit.shCuatro pasos pausados:
- crear carrito
- añadir 30 hamburguesas (precio real ₹4950)
PUT { total: 1 }: mass assignment, el backend se lo tragaPOST /checkout: el backend firma elorderDetailscontotal: 1
Al final el script descarga la pública del backend y verifica la firma con
openssl dgst -verify. La firma cuadra sobre un dato manipulado. Eso es
trust boundary violation.
Abre http://localhost:8080, añade hamburguesas hasta que el total cuadre
(p.ej. 30 × ₹165 = ₹4950), y pulsa el botón rojo Run mass assignment del
bloque "Security demo". Verás el total caer de ₹4950 a ₹1 al instante.
Después dale a Proceed to checkout y ves la pantalla de "Order confirmed".
.
├── docker-compose.yml
├── exploit.sh
├── README.md
├── backend/ (Flask + RSA. Mass assignment + firma.)
└── frontend/ (UI genérica BurgerLab. nginx.)
El backend firma lo que el cliente le mandó, no lo que el catálogo debería haber dado. La firma certifica que nadie tocó el dato después. No certifica que el dato sea verdad.
POST /cart— crear carritoPOST /cart/<id>/items— añadir items (calcula total con catálogo)PUT /cart/<id>— vulnerable: acepta cualquier campo del JSONPOST /cart/<id>/checkout— firma elorderDetailscon la llave privadaGET /public_key— devuelve la public key en PEM (para verificar firmas)GET /catalog— productos disponibles