7.4 KiB
7.4 KiB
1. Pre-flight y preparación (reglas de compromiso)
- 1.1 Redactar y firmar la autorización (alcance, IPs origen Kali+localhost, ventana, contacto) y guardarla como cabecera de
docs/SECURITY_FINDINGS.md. - 1.2 Tomar snapshot/backup de BD y volumen; probar la restauración. Preparar clon de staging.
- 1.3 Crear cuentas de test dedicadas (
sec_test_portal,sec_test_user, opcional manager); anotar grupos y partners. - 1.4 Confirmar topología de prod vía SSH (
ss -tlnp,ps aux | grep odoo, config nginx/traefik,odoo.conf, fail2ban, firewall, versión exacta de Odoo).
2. Entregables de documentación (docs/)
- 2.1 Crear
docs/SECURITY_AUDIT_CHECKLIST.md: checklist de prevuelo con ítems markables por los 3 frentes + infra, cada uno con criterio pass/fail. - 2.2 Crear
docs/SECURITY_AUDIT_RUNBOOK.md: comandos paso a paso de la auditoría activa (nmap, hydra/patator, testssl.sh, nikto, ffuf, invocación de scripts) con las salvaguardas de la sección 1. - 2.3 Crear
docs/SECURITY_FINDINGS.md: registro con severidad/evidencia/estado, sembrado con H1–H5 + hallazgos de infra.
3. Scripts de auditoría (scripts/security/, no destructivos, credenciales por parámetro/env)
- 3.1
odoo_acl_probe.py: autentica como portal/usuario de test vía API externa y prueba matriz read/write/create/unlink sobregroup.order,group.order.slot,product.supplierinfo,res.partner,res.users,account.move,sale.order(de otro partner),ir.config_parameter,ir.attachment,account.banking.mandate,res.partner.bank. - 3.2
idor_probe.py: como portal de test, iteraorder_id/group_order_idenload_eskaera_page,load_products_ajax,add_to_eskaera_cart,eskaera_checkout,check_group_order_statusy detecta fuga de catálogo/precios de grupos ajenos; incluir IDOR vertical sobre/my/orders/<id>y/my/events/<id>. - 3.3
bruteforce_test.sh: hydra/patator controlado contra cuenta de test en/web/loginy contra la ruta API (/web/session/authenticate,/xmlrpc/2/common); verifica baneo de la IP de Kali por fail2ban. - 3.4
csrf_poc.html: formulario cross-site que fuerzaPOST /eskaera/clear-carty/eskaera/confirmdesde sesión logueada (para demostrar H3 antes del fix). - 3.5
web_recon.sh: nmap + testssl.sh + nikto + ffuf sobre rutas Odoo conocidas (/web/database/manager,/web/database/selector,?debug=1,/web/webclient/version_info,.git/) y chequeo de cabeceras/cookies.
4. Ejecución de la auditoría activa (registrar todo en el findings register)
- 4.1 Frente 1 (fuerza bruta): ejecutar 3.3; medir umbral/tiempo de baneo web y API; revisar política de contraseñas (
auth_password_policy), 2FA (auth_totp),auth_signupno invitado, gestor de BD. - 4.2 Frente 2 (acceso a datos vía API): ejecutar 3.1 y 3.2 (baseline pre-fix); documentar accesos indebidos (valida H1, H2, H4).
- 4.3 Frente 3 (vectores inadvertidos): ejecutar 3.4 (valida H3), 3.5 (TLS, cabeceras, superficie web, versión/CVEs) y revisar
t-raw/XSS (valida H5).
5. Fixes de código — website_sale_aplicoop
- 5.1 (H1) En
security/ir.model.access.csv: sustituir la filaaccess_group_order_base(grupo vacío) por lectura internabase.group_user1,0,0,0; idemaccess_group_order_slot_base; mantener filas de manager para escritura; añadir ACL de portal de solo lectura para el slot solo si el controlador lo lee sinsudo(). - 5.2 (H2) Identificar en plantillas/controladores qué campos de
product.supplierinfolee el portal (origen del producto, proveedor principal víaproduct.seller_ids) y confirmar que el pricing va porsudo()encontrollers/website_sale_pricing.py. - 5.3 (H2, preferido) Preparar origen + proveedor principal en el controlador vía
sudo()y pasarlos resueltos a la plantilla (sin lógica en QWeb); luego eliminar la ACL de portal deproduct.supplierinfo(fila 6 del CSV) y la record rulerule_product_supplierinfo_portal_read. - 5.4 (H2, fallback si el render no se puede mover al controlador) Sustituir
domain=[(1,'=',1)]derule_product_supplierinfo_portal_readpor un dominio acotado a los productos de los grupos del usuario, sin exponer campos de coste/precio. - 5.5 (H3) En
controllers/website_sale.py: convertirsave-order,confirm,clear-cart,save-cartdetype="http"+csrf=Falseatype="json"(plantilla:confirm_order_from_portal); devolverdict. - 5.6 (H3) Ajustar el JS de
static/src/js/(solo transporte: fetch con envelope JSON-RPC y lectura deresult), sin lógica de negocio en JS. - 5.7 (H4) En
controllers/website_sale.py: añadir comprobación de pertenencia trasexists()/stateenload_eskaera_page,load_products_ajax,add_to_eskaera_cart,eskaera_checkout,check_group_order_status, reutilizando_get_consumer_group_for_user(retorno vacío/redirect) o_validate_user_group_access(fallo duro); mantener bypass de usuario interno (share == False). - 5.8 (H5) En
views/load_from_history_templates.xml: sustituirt-rawen<script>por<script type="application/json">leído por el JS. - 5.9 Bump de versión en
website_sale_aplicoop/__manifest__.py(18.0.X.Y.Z).
6. Fix versionable de infra — account_banking_mandate_batch
- 6.1 Añadir
groups_ida la server action de mandatos SEPA enaccount_banking_mandate_batch/data/server_action.xmlpara restringir quién puede lanzarla.
7. Tests (extender los existentes de website_sale_aplicoop/tests/)
- 7.1
test_record_rules.py/test_multi_company.py: aserciones de que el portal NO puede write/creategroup.ordernigroup.order.slot(H1) ni leerproduct.supplierinfoajeno (H2). - 7.2
test_group_order_status_endpoint.py: un portal fuera del grupo NO obtiene datos de los endpoints de lectura/ajax (H4); un miembro sí. - 7.3 Test de que los endpoints de estado convertidos a
type="json"funcionan same-origin y que el flujo de checkout/carrito sigue operando (H3).
8. Hardening de infra (servidor de prod; no versionable — verificar contra el checklist)
- 8.1
odoo.conf:admin_passwdfuerte,list_db=False,dbfilterpor host,proxy_mode=True,workers>0,limit_*,without_demo=True,db_passwordfuerte; log parseable por fail2ban. - 8.2 nginx/traefik:
limit_reqen/web/login,/web/session/authenticate,/jsonrpc,/xmlrpc; bloquear/restringir/web/database/*; HSTS + cabeceras; TLS fuerte; cookiesession_idSecure/HttpOnly/SameSite; upgrade de/websocket. - 8.3 fail2ban: jails para login web y API (IP real vía
proxy_mode), jail de 429 de nginx yrecidive; verificar baneo con 3.3. - 8.4 BD/secretos: confirmar 5432 no expuesto por firewall; usuario de BD con mínimos privilegios; externalizar secretos fuera de ficheros versionados.
9. Verificación y calidad
- 9.1 Re-ejecutar 3.1/3.2 (deben denegar lo que antes permitían) y 3.4 (debe fallar tras el fix); actualizar el findings register a resuelto/verificado.
- 9.2 Tests del addon:
docker-compose run odoo odoo -d odoo --test-enable --stop-after-init -u website_sale_aplicoop(usarrun, noexec). - 9.3 Verificación end-to-end del portal (carrito, save-order, confirm, clear-cart, checkout) tras la conversión a
type="json". - 9.4 Calidad:
make format/make lint(black línea 88 + isort + flake8 + pylint-odoo); sin_()en definiciones de campo;pre-commit run --all-files. - 9.5 Cerrar cada ítem del checklist de prevuelo con evidencia.