En primer lugar, tenemos que entender el problema principal sobre CSRF; el servidor confía en todas las solicitudes que enviamos, en otras palabras, el servidor no garantiza que la solicitud haya sido enviada conscientemente por un usuario legítimo, por este motivo, debemos agregar un elemento para identificar cada solicitud correctamente.
La idea principal para protegerse contra CSRF es la implementación de un elemento único y esto debe ser difícil de predecir, entonces las medidas como el token o CAPTCHA son buenas soluciones. El CAPTCHA no es eficiente en la mayoría de los casos, porque a un usuario no le gusta introducir valores en el CAPTCHA para cada sitio que visita, recuerde que debe haber un equilibrio entre la seguridad y el rendimiento, de esta manera, la solución principal será se token.
Ahora, verificar el origen no es suficiente para proteger contra CSRF; Imagine un sitio web vulnerable a XSS, puede inyectar un script para ejecutar un ataque CSRF; otro ejemplo podría ser un módulo editable en el que puede agregar o editar elementos para personalizar una página web que podría ser visitada por cada usuario de la aplicación, puede agregar algo como esto:
<img src="http://mywebsite/transfer?account=123456&quantity=1000000" />
Si la aplicación web valida el origen, en este caso, la solicitud será válida porque pertenece al mismo origen.
Espero que esta información te ayude.