There's been many occasions where a user-specific payload has been generated (shopping cart, check out, config settings, processing results) and the user needs to be directed to a new destination with the data, but I want to avoid non-securely passing data as URL or form parameters or having to enable and/or leverage session variables.
We've encountered issues where the content could be blocked due to complex WAF rules that are beyond our editable control... especially if there's anything that resembles HTML or contains certain sequences. There's also abuse issues as automated software can scan the form, fuzz the parameters in order to blindly auto-post to the final script. We experienced this in the form of carding (aka credit card stuffing) on some non-profit donation forms.
To prevent abuse, we've added hCaptcha, CSRF, fingerprinting, IP reputation and some other countermeasures, but there's been some sophisticated abuses where everything (remote IP, form payload, browser) is completely different, but it's obvious that it's the same abuser due to the automated schedule and occurrence of failures.
The most impactful workflow has been to:
- display a verification page
- Create an object with data unique to the order (IP, email, total amount) , temporarily cache it server-side and generate a token to add to the form
- Upon submission, and prior to performing any transaction, use the UUID to perform a look-up of cached data. If the look-up data doesn't exist or doesn't match the form/CGI data, reject the attempt.
- Added bonus: If no cached data exists, sleep for a second or two and then return a bogus "credit card is invalid" message.
We've also used this script on Contact & "Thank you" pages. On some older applications, the response is displayed on the same page without redirecting or using history.pushState(null, null, "/myUrl");
to prevent accidental POST resubmission, but some app-based browsers seem to be blindly retriggering the form post when reopening the app. We haven't been able to determine the actual cause, but capturing the response message, adding it to an object, caching and redirecting to a new page with the UUID to display the content has prevented the form report/replay issues from reoccurring.
Here's the TempCache UDF. A simple cfml example has been included:
https://gist.github.com/JamoCA/fd43c189379196b6a52884affea3ad51
Top comments (0)