Reglas de seguridad
Estas son las reglas de seguridad que deben cumplir los recursos de terceros. Cada punto surge de tipos de incidentes reales.
Salida: XSS
- Al mostrar entradas del usuario, usa siempre
{{ }}(con escape). - Usa
{!! !!}solo con HTML que el núcleo ya sanitizó (el cuerpo del editor,getContent()). En cuanto metes un valor sin sanitizar, tienes un XSS. - Para insertar valores en un contexto JS, usa
@json($value)o el filtro|escapejs. No armes scripts concatenando cadenas.
Entrada: la validación va en el servidor
- La validación en pantalla (JS) es solo una comodidad. Repite toda la validación en la acción proc (servidor).
- Convierte los números con
(int)y verifica los valores con lista permitida usandoin_array(..., true). - Mientras uses los parámetros enlazados del Query XML, la inyección SQL queda bloqueada, pero refuérzalo con
filter="number"ynotnull. Pon siempre notnull en las condiciones clave para que no se ejecute un update/delete sin condición.
CSRF y diseño de acciones
- Toda operación que modifique datos debe ser una acción proc + POST. El núcleo verifica el token CSRF automáticamente.
- Nunca modifiques datos desde GET (disp). Una estructura en la que un solo enlace ejecuta un borrado también evade la verificación CSRF.
- Solo a los callbacks que llama un servidor externo agrégales
standalone="true" check-csrf="false", y dentro de esa acción haz tu propia verificación (firma, token de estado, reconfirmación entre servidores). No confíes en valores que pasaron por el navegador.
Verificación de permisos
- No dependas solo del atributo
permissionde module.xml: en operaciones que requieren comprobar al dueño (editar mi publicación, etc.), comparamember_srldentro de la acción. - Protege las funciones de administración en dos capas:
permission="manager"+ control de permisos también en la pantalla. Ocultar solo el botón en pantalla no es protección.
Carga de archivos
- Revisa las extensiones con una lista permitida (las listas de bloqueo se pueden evadir).
- Pon un límite de tamaño y no uses el nombre original del archivo al guardarlo: genera uno nuevo.
- Para que los archivos ejecutables (.php, etc.) no se ejecuten desde la ruta de carga, usa la ruta del módulo de archivos del núcleo (
files/attach). La configuración del servidor web bloquea la ejecución de PHP en esa ruta.
Almacenamiento de secretos
- Al guardar tokens y claves en la base de datos, guárdalos como hash (si solo necesitas compararlos) o cifrados (si necesitas descifrarlos).
Zittme\Framework\Securitydel núcleo incluye herramientas de cifrado. - Si creas archivos de estado temporales bajo
files/cache, verifica que no se puedan acceder directamente por web. Si es una ruta nueva que no está en las reglas de bloqueo del servidor web, debes agregar una regla. Hubo un incidente real en que esta ruta quedó expuesta con HTTP 200. - No escribas credenciales directamente en el código. Guárdalas en los ajustes del módulo (insertModuleConfig) y muéstralas enmascaradas en pantalla.
Integraciones externas
- Callbacks que recibe tu servidor: no confíes en valores que pasaron por el navegador; vuelve a verificarlos con comunicación entre servidores (monto del pago, resultado de la autenticación, etc.).
- En el intercambio de códigos de autorización, usa protecciones estándar como el token de estado (state) y PKCE.
- Verifica que la respuesta no envíe un Set-Cookie innecesario. Si en un callback entre sitios se emite una nueva cookie de sesión, puede sobrescribir la sesión existente del usuario.
Lista de revisión final
- ¿Hay algún lugar donde la entrada del usuario se muestre sin escape?
- ¿Hay algún lugar donde los datos cambien por GET sin proc?
- ¿Hay consultas update/delete sin condición?
- ¿La revisión de extensión y tamaño de las cargas está en el servidor?
- ¿Hay secretos guardados en texto plano o en rutas expuestas a la web?