Linked Questions

Popular Questions

ColdFusion CSRF XSS attack prevention

Asked by At

I have implemented the csrfGenerateToken and csrfVerifyToken functions in trying the prevent a CSRF attack.

I have set up the webpage header with these:

set X-XSS-Protection "1; mode=block"
always set X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
Strict-Transport-Security "max-age=63072000" env=HTTPS

I have done some research and proceed as recommended by Adobe doing something like this:

<cfset tokenVar = 't' & lCase( hash( createUUID() & randRange( 1000, 100000 ), 'MD5', 'UTF-8', 250 ) )>
<form action="updateprofile.cfm" method="post">
    <input type="hidden" name="f#hash( 'tokenVar', 'SHA-256', 'UTF-8')#" value="#tokenVar#">
    <input type="hidden" name="f#hash( 'formToken', 'SHA-256', 'UTF-8')#" value="#csrfGenerateToken( tokenVar, true )#">
    <input type="text" name="emailAddress" value="#EmailAddress#">
    <input type="text" name="phoneNumber" value="#PhoneNumber#">
    <input type="submit" name="btnSubmit" value="Change Profile Info">
</form>

Updateprofile.cfm would have:

<cfparam name="FORM[ 'f' & hash( 'tokenVar', 'SHA-256', 'UTF-8')]" default="0">
<cfparam name="FORM[ 'f' & hash( 'formToken', 'SHA-256', 'UTF-8')]" default="0">
<cfif not csrfVerifyToken( FORM[ 'f' & hash( 'formToken', 'SHA-256', 'UTF-8')], FORM[ 'f' & hash( 'tokenVar', 'SHA-256', 'UTF-8')] )>
    <!--- CSRF attack. Clear cookies and kick user out --->
    <cfinclude template="clearcookies.cfm">
    <cflocation url="signin.htm" addToken = "no">
</cfif>

This will work if 2 accounts are signed in on the same browsers and if one tries to update the other. However, when I simply saved a copy of the resulting html from one of them and save it as csrf-attack.htm locally:

<html><body>
<script>history.pushState('', '', '/')</script>
<form action="http://www.exsample.com/updateprofile.cfm" method="post">
    <input type="hidden" name="f41BE6B4E09CBA69BDB76DBB69B493E8D49F5DD9ED230085913397B4C751D4E60" value="t93315a7c3ecb43d4d1b9422da97ffb09">
    <input type="hidden" name="f08DFC2607D4119D7B16B4C01DC5C00F54B044DC937257ABC411F9A7E55BB4191" value="A0EED67C55F5E17683E2E1B21FF3454FE690E0B1">
    <input type="text" name="emailAddress" value="[email protected]">
    <input type="text" name="phoneNumber" value="1-222-3333">
    <input type="submit" name="btnSubmit" value="Change Profile Info">
</form>
</body><html>

I processed the original form to update the phone number to 1-333-4444. Then I came back to the form again. At this time a new CSRFToken should have been created because ForceNew was set to true.

Then I go to the static HTML page that I have saved, and simply changed the value of the email address to [email protected] instead of [email protected] with the old token, then clicked the "Change Profile Info" button, I was able to update it to the site!!

Am I doing something wrong or is it how it works? It seems that the token is useless if I can simply copy the token values and manipulate the content, then post it. How can I mitigate issue like this on the receiving page?

Thanks in advance.

Related Questions