Browse files

FC-3174 add CSRF token generation/validation on all formtools forms

  • Loading branch information...
justincarter committed Nov 26, 2018
1 parent 2b7eaf5 commit 19480f2e91b7f3c49a7af14599bc6e4b919fdd3e
Showing with 24 additions and 5 deletions.
  1. +6 −0 packages/forms/configSecurity.cfc
  2. +6 −2 tags/formtools/form.cfm
  3. +12 −3 tags/formtools/processform.cfm
@@ -11,6 +11,12 @@
ftSeq="2" ftFieldset="Directories and Storage" ftLabel="Password hashing algorithm"
ftHint="" hint="Algorithm used to encrypt passwords in the database">

<!--- Form security --->

<cfproperty name="bCSRFTokens" type="boolean" ftType="boolean" default="1"
ftSeq="5" ftFieldset="Form Security" ftLabel="Enable CSRF Tokens on forms"
ftHint="Check this box to enable CSRF token generation/validation on all forms by default">

<!--- Password policy --->

<cfproperty name="passwordMinLength" type="integer" ftType="integer" default="6" ftValidation="required"
@@ -58,6 +58,7 @@ It just ignores the inner ones.
<cfparam name="attributes.ajaxTimeout" default="30">
<cfparam name="attributes.ajaxTarget" default=""><!--- jQuery selector specifying the target element for the form response. Defaults to the FORM element. --->
<cfparam name="attributes.bAddFormCSS" default="true" /><!--- Add relevent form layout css --->
<cfparam name="attributes.bGenerateCSRFToken" default="#application.fapi.getConfig("security", "bCSRFTokens", "true")#" /><!--- Generate CSRF token to the form --->
<cfparam name="attributes.bFieldHighlight" default="true"><!--- Highlight fields when focused --->
<cfparam name="attributes.bFocusFirstField" default="false" /><!--- Focus on first form element. --->
<cfparam name="attributes.defaultAction" default="" /><!--- The default action to be used if user presses enter key on browser that doesn't fire onClick event of first button. --->
@@ -184,8 +185,11 @@ It just ignores the inner ones.
<input type="hidden" name="SelectedObjectID" class="fc-selected-object-id" value="" #tagEnding#><!--- Hidden Field to take a UUID from the attributes.SelectedObjectID on ft:button --->

<input type="hidden" name="farcryFormValidation" id="farcryFormValidation#attributes.Name#" class="fc-server-side-validation" value="#attributes.Validation#" #tagEnding#><!--- Let the form submission know if it to perform serverside validation --->

<cfif attributes.bGenerateCSRFToken>
<input type="hidden" name="FarcryFormToken" value="#csrfGenerateToken(attributes.Name)#">


@@ -39,12 +39,13 @@
<cfparam name="attributes.Exit" default="false"><!--- @@hint: If set to true the ft:form on the page will not show it's contents after this process runs. Note this doesn't stop page execution, just does not render ft:form contents. @@default: false --->
<cfparam name="attributes.bSpamProtect" default="false"><!--- Instantiates cfformprotection to ensure the button is not clicked by spam. --->
<cfparam name="attributes.stSpamProtectConfig" default="#structNew()#" /><!--- config data that will override the config set in the webtop. --->
<cfparam name="attributes.bValidateCSRFToken" default="#application.fapi.getConfig("security", "bCSRFTokens", "true")#" /><!--- Validate CSRF token on the form --->

<cfset variables.EnterFormProcess = false>

<cfif structKeyExists(form, "FarcryFormSubmitted")>

<!--- I18 conversion of action and exludeAction lists --->
<cfloop from="1" to="#listlen(attributes.action)#" index="i">
<cfif listlen(attributes.rbkey) lt i>
@@ -81,7 +82,7 @@

<cfif isDefined("FORM.FarcryFormSubmitButton") AND len(FORM.FarcryFormSubmitButton)>

<cfif listFindNoCase(attributes.action,FORM.FarcryFormSubmitButton) OR attributes.action EQ "*">
<cfif NOT listFindNoCase(attributes.excludeAction,FORM.FarcryFormSubmitButton)>
<cfset variables.EnterFormProcess = true />
@@ -95,7 +96,15 @@
<cfif NOT variables.EnterFormProcess>

<cfif attributes.bValidateCSRFToken>
<cfif NOT structKeyExists(form, "FarcryFormToken") OR NOT csrfVerifyToken(form.FarcryFormToken, form.FarcryFormSubmitted)>
<!--- csrf token not found or invalid --->
<skin:bubble message="There was a problem with the form submission. Please try again." tags="error" />
<cfexit method="exittag">

<cfif attributes.bSpamProtect>
<cfif not structkeyexists(session,"stFarCryFormSpamProtection") or not structkeyexists(session.stFarCryFormSpamProtection,form.farcryFormSubmitted) or not structkeyexists(session.stFarCryFormSpamProtection[form.farcryFormSubmitted],FORM.FarcryFormSubmitButton)>
<!--- User was sessionless until they POST'd (happens behind reverse proxies) - set up as best we can here --->

0 comments on commit 19480f2

Please sign in to comment.