OWASP ZAP CSRF Token Authentication

68 views
Skip to first unread message

Adam Lawson

unread,
Jan 28, 2019, 11:37:05 AM1/28/19
to OWASP ZAP Developer Group
Greetings, 

I have been racking my brain for a few days now on how to authenticate the Damn Vulnerable Web App using ZAP. To my understanding, I must create an authentication script using zest and load this into my context before attacking the website. I have done this and added the anti-csrf token to the list and loaded the context into my script, however I am still not able to fully spider the website and my login request always fail with an invalid CSRF token message. How can I resolve this issue? Is there something I am missing?

Screenshot_2.png
Screenshot_3.png

hauschu...@gmail.com

unread,
Jan 29, 2019, 2:46:53 AM1/29/19
to OWASP ZAP Developer Group
Hello!

What is sent in the POST request? That is, highlight the appropriate request in the history tab (not the zest tab)

Have you tried handling the CSRF token by going into the Tools/Options/Anti-CSRF-Tokens menu? You should be able to define it here (if it has a consistent name across pages), enable it and then ZAP will handle it.
Untitled.jpg

Adam Lawson

unread,
Jan 29, 2019, 8:16:40 AM1/29/19
to OWASP ZAP Developer Group
I have added the anti-csrf token to zap's list. In the post request it is being sent the username,password,Login and token. I have it configured as shown in my screenshots.
Screenshot_4.png
Screenshot_5.png
Screenshot_6.png
Screenshot_7.png
Screenshot_8.png
Screenshot_9.png

hauschu...@gmail.com

unread,
Jan 30, 2019, 2:36:55 AM1/30/19
to OWASP ZAP Developer Group
ah ok!

Based on screenshot8, it looks the csrf token is being handled just fine, but that it isn't handling the phpsessionid cookie. ZAP normally handles those automatically, but if you are using a Zest script then you have to specify what it should handle dynamically vs statically vs not at all. 

Since your login is script-based, I would go in to whichever POST request is the one actually sending the auth parameters and add another header in the request, something like Cookie: PHPSESSID={{phpid}}.

Then make sure the {{phpid}} variable is defined prior to that request, and captured from whatever response header sets it. (similar to how you have csrf1 right now)

Give that a shot!

thc...@gmail.com

unread,
Jan 30, 2019, 4:57:03 AM1/30/19
to zaproxy...@googlegroups.com
Hi.

With the latest weekly releases [1] the Form-based authentication
already handles anti-CSRF tokens (added to Options > Anti-CSRF Tokens).

I'd suggest giving that a try, otherwise the following steps are known
to work:
https://github.com/zaproxy/zaproxy/issues/2093#issuecomment-163002923


[1] https://github.com/zaproxy/zaproxy/wiki/Downloads#zap-weekly

Best regards.

Adam Lawson

unread,
Jan 30, 2019, 10:58:31 AM1/30/19
to OWASP ZAP Developer Group
Oh ok, how would I got about assigning the variable through zest? I'm trying to find documentation on it but there isn't much. I'm confused as to which assignment I have to choose.
Screenshot_10.png

kingthorin+owaspzap

unread,
Jan 30, 2019, 4:19:52 PM1/30/19
to OWASP ZAP Developer Group
It doesn't have to be Zest. There's a FAQ related to scanning DVWA: https://github.com/zaproxy/zaproxy/wiki/FAQvulnappdvwa

hauschu...@gmail.com

unread,
Jan 31, 2019, 3:19:38 AM1/31/19
to OWASP ZAP Developer Group
Since there appear to be good documents regarding DVWA specifically, go follow THC and KINGTHORIN's links, they're bound to steer you in the right direction!

For any future needs you might have, I generally use the 'string delimiter' option for Zest variable assignment (shown here). 

The delimiter ones you need to mark what comes immediately before and immediately after the value that you want to capture. The other ones should be used to assign some kind of form field (username, for example), or the string and number ones are pretty self explanatory. 
Untitled.jpg

hauschu...@gmail.com

unread,
Jan 31, 2019, 3:22:33 AM1/31/19
to OWASP ZAP Developer Group
Also note that you insert this variable AFTER the request/response you want to capture the value from. 

Then that variable can be referenced in later requests and will be automatically used. Ie, in the above screenshot, I could include the following header in a subsequent request and it would populate the set value.

X-Cloud-Trace-Context: {{test}}
Reply all
Reply to author
Forward
0 new messages