OWASP Top 10 (edición 2021) aplicado a ERPNext
ERPNext es razonablemente seguro de partida, pero las apps Frappe a medida pueden introducir vulnerabilidades si no se desarrollan con cuidado. Este es el mapa de los 10 vectores OWASP y cómo se mitigan en una instalación ERPNext real.
A01: Broken Access Control
Mitigación: Roles y permisos por DocType, por campo y por workflow. Revisar configuración de Role Permission Manager y Custom DocPerm. Comprobar que ningún rol no privilegiado tiene acceso a DocTypes administrativos. Auditoría trimestral.
ERPNext por defecto: Permisos granulares nativos por DocType, campo y rol; Role Profile para agrupar.
A02: Cryptographic Failures
Mitigación: TLS 1.2+ obligatorio con HSTS. Hashing de contraseñas bcrypt. Cifrado at-rest si aplica el cumplimiento. Datos sensibles (DNIs, IBAN) cifrados a nivel de campo si la criticidad lo exige.
ERPNext por defecto: Bcrypt para passwords; soporte de Field Encryption para datos sensibles.
A03: Injection
Mitigación: Uso de la ORM de Frappe (frappe.db.get_list, frappe.db.exists, get_doc) que parametriza automáticamente. Evitar frappe.db.sql con string interpolation; usar siempre placeholders %s o filtros estructurados.
ERPNext por defecto: ORM segura por defecto; los desarrolladores deben usar filtros estructurados, no SQL crudo.
A04: Insecure Design
Mitigación: Threat modeling al diseñar apps custom: identificar entidades sensibles, flujos privilegiados, integraciones externas. No exponer en /api métodos que no deberían ser públicos.
ERPNext por defecto: Decoradores @frappe.whitelist() controlan qué métodos son llamables vía API.
A05: Security Misconfiguration
Mitigación: developer_mode = 0 en producción; server_script_enabled = 0 salvo necesidad auditada; configuración Nginx con headers de seguridad; sin endpoints de debug expuestos. Bench config con permisos restrictivos.
ERPNext por defecto: Config en site_config.json con encrypted_password y permisos 640.
A06: Vulnerable Components
Mitigación: Política de actualización mensual de Frappe + ERPNext + dependencias Python (pip) + Node.js. Monitor de advisories. Versiones LTS soportadas (no quedarse en versiones EOL).
ERPNext por defecto: bench update gestiona el ciclo; rama LTS recomendada para producción.
A07: Identification & Authentication Failures
Mitigación: 2FA obligatorio para roles privilegiados; SSO si aplica. Política de contraseñas con longitud mínima y rotación. Account lockout tras intentos fallidos. Sesiones con expiración razonable.
ERPNext por defecto: 2FA TOTP nativo; SSO via SAML/OAuth2; configurable Time After Inactive Logout.
A08: Software & Data Integrity
Mitigación: Verificación de checksums en backups. Code review específico de seguridad para apps custom antes de deploy. CI/CD con linters de seguridad (bandit, safety). Hashes de firma para releases internas.
ERPNext por defecto: Frappe Cloud usa firmas; en self-hosted aplicar bench update solo desde fuentes verificadas.
A09: Security Logging & Monitoring
Mitigación: Activity Log activado para acciones privilegiadas. Logs de Nginx y Frappe centralizados. Alertas en intentos de login fallidos masivos, modificaciones de roles, accesos fuera de horario laboral. Retención mínima 90 días.
ERPNext por defecto: Activity Log nativo + bench logs; envío a SIEM via filebeat o vector.
A10: Server-Side Request Forgery (SSRF)
Mitigación: Validar URLs en integraciones que reciban URLs como parámetro. Whitelist de dominios externos contactables desde el backend. Bloqueo de redirecciones automáticas a IPs internas en hooks que llamen URLs.
ERPNext por defecto: Frappe utility frappe.utils.make_request con tiempo y allowlist configurables.
Casos prácticos
¿Cómo está protegido ERPNext contra CSRF?
Frappe Framework incluye protección CSRF nativa: cada formulario incluye un token X-Frappe-CSRF-Token que se valida en cada POST. La cookie de sesión es HttpOnly y SameSite. Para llamadas desde apps externas, se usan API keys/secret en lugar de cookies. La protección está activa por defecto; lo único a vigilar son apps custom que llamen frappe.flags.skip_csrf=True (debería evitarse).
¿Qué tipos de XSS pueden aparecer en ERPNext?
Frappe escapa por defecto en sus templates jinja con autoescape. Los riesgos aparecen en:
- **Custom Print Format** con HTML injection si el usuario tiene Customize permission.
- **Custom Scripts del lado cliente** que renderizan input sin escapar.
- **Markdown Editor** con HTML inline si está habilitado sin sanitización.
Mitigación: limitar Customize permission a System Manager, code review de Custom Scripts, sanitización de HTML en custom apps que lo permitan.
¿Cómo audito una app Frappe custom para OWASP?
Proceso en cuatro pasos:
- **Linting estático** con bandit (Python) y semgrep (reglas Frappe-specific).
- **Code review manual** buscando **frappe.db.sql** con interpolación, decoradores **@whitelist** en métodos sensibles, métodos sin permission check, exposición de datos en /api.
- **Pruebas dinámicas**: pentesting de los endpoints de la app con un usuario sin privilegios.
- **Revisión de Custom Scripts JS y Print Formats**.
Pentesting de ERPNext
Dos modalidades habituales:
- **Caja blanca**: con acceso al código y a un usuario admin del staging para probar todos los flujos.
- **Caja gris**: con acceso a un usuario de rol limitado simulando un atacante interno.
El pentesting funcional se centra en autorizaciones (IDOR, escalado vertical/horizontal), inyección, autenticación, y endpoints expuestos. Útil antes de una auditoría ISO 27001 o cuando una app custom va a producción por primera vez.
Conclusión
OWASP Top 10 aplicado a ERPNext es trabajo de configuración + disciplina en el desarrollo de apps custom. ¿Quieres una auditoría OWASP de tu ERPNext o de una app Frappe a medida? [Contáctanos](/contacto): code review específico, pentesting funcional y plan de remediación priorizado.