Esta es la pieza de desarrollo seguro de nuestra serie sobre seguridad en ERPNext. Para el panorama completo —producto, servidor y procedimientos— tienes la guía de seguridad de ERPNext; lo que viene a continuación es el detalle de código y configuración.
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, igual que en cualquier framework. Este es el mapa de los 10 vectores OWASP y cómo se mitigan en una instalación ERPNext real, con lo que cubre el producto y lo que depende de ti.
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.
Mitigacion: 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
Un pentesting de ERPNext tiene sentido antes de una auditoría ISO 27001 o cuando una app custom llega a producción por primera vez, y se plantea siempre en dos modalidades habituales según el acceso que se le dé al equipo que lo ejecuta:
- 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.
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: code review específico, pentesting funcional y plan de remediación priorizado.
Si prefieres no llevar esto tú
Buena parte de estos vectores se cierran desde sistemas, y esa parte la puedes delegar. El hosting gestionado te entrega el servidor endurecido y con copias de seguridad en marcha, y el mantenimiento mantiene Frappe, ERPNext y sus dependencias al día, que es la forma más barata de no acumular un A06 por simple dejadez.