Usted puede hacer cualquiera de los dos. Depende del nivel de seguridad que desee.
La API de seguridad de la empresa OWASP (ESAPI) utiliza el método único token por sesión de usuario. Ese es probablemente un método bastante efectivo suponiendo que no tiene agujeros XSS y tiene tiempos de espera de sesión razonablemente cortos. Si permite que las sesiones permanezcan con vida durante días o semanas, entonces este no es un buen enfoque.
Personalmente, no encuentro difícil el uso de un símbolo diferente para cada instancia de cada forma. Guardo una estructura en la sesión del usuario con pares clave-valor. La clave para cada elemento es la ID del formulario, el valor es otra estructura que contiene el token y una fecha de vencimiento para ese token. Normalmente, solo permitiré que un token viva 10-20 minutos, luego caducará. Para formularios más largos, puedo darle un tiempo de expiración largo.
Si desea ser capaz de soportar el mismo formulario en varias pestañas del navegador en la misma sesión, entonces mi método se vuelve un poco engañoso, pero aún podría hacerse fácilmente teniendo identificaciones de formulario únicas.
¿Quieres decir que cada instancia de cada formulario tiene su propio token? Es decir. ''? – Industrial
Creo que tener un único token por sesión es razonable siempre y cuando no los envíe a través de http (solo https). Comparten muchas preocupaciones de seguridad con los identificadores de sesión. Si tiene XSS, el atacante puede abrir iframes, leer los tokens y hacer CSRF de todos modos. – Erlend
Si tiene XSS, ya ha perdido. Los nonces adicionales por formulario no lo salvarán (el atacante podrá obtener un nuevo formulario, con nueva versión, completarlo y enviarlo, tal como lo haría el usuario). El valor único por usuario es absolutamente suficiente para CSRF. – Kornel