ColdFusion Hash() Defaults Changed — Here’s How to Fix It With Regex

Starting with ColdFusion 2021 Update 14 and ColdFusion 2023 Update 8, the default hashing algorithm changed from CFMX_COMPAT to SHA-256.

Any code relying on Hash(value) without explicitly specifying the algorithm can:

  • Behave differently after an upgrade
  • Break verification logic
  • Trigger security scanner findings (Fixinator)

Fixinator provides the following warning:

Use of a weak hashing algorithm such as MD5 (the algorithm used by CFMX_COMPAT). This can also be a compatibility issue (after CF2023 update 8 and CF2021 update 14) if the hash algorithm is not specified. The default has changed from CFMX_COMPAT to SHA-256 in those releases.
In CFML, Hash() can appear in two contexts:
  1. Output expressions: #Hash(value)#
  2. Script/logic: Hash(value)

Any global refactor must account for both forms. It took me a few iterations to get what I needed.

This article demonstrates how to perform a global search and replace using REGEX in VS Code.

Note(s):

  • In the VS Code search panel REGEX is enabled with the .* icon to the right of the search input.
  • The ColdFusion app I was working with used only Hash() and not hash().
  • You could use a case insensitive search with the REGEX from Iteration 3 with “Preserve Case” for the replace input to account for Hash() vs hash() if necessary.
  • Your mileage may vary on this solution.

WARNING

PLEASE PREVIEW THE RESULTS OF YOUR SEARCHES BEFORE DOING THE REPLACE.


Iteration 1

This was my first attempt.

Search: #Hash\(\s*([^)]*?)\s*\)#
Replace: #Hash($1, "SHA-256", "UTF-8")#
Bad Match: <a href="edit.cfm?newsID=#qData.newsID#&verifyID=#Hash(qData.newsID, ">Edit</a>
Bad Result: <a href="edit.cfm?newsID=#qData.newsID#&verifyID=#Hash(qData.newsID, ">Edit</a>
Why it’s bad: Caused incorrect code if the algorithm argument already existed.

Iteration 2

Based on the failure of the first attempt I made the following second attempt.

Search: #Hash\(\s*([^,\)]+)\s*\)#
Replace: #Hash($1, "SHA-256", "UTF-8")#
Missed Match:

<cfif Hash(URL.newsID) EQ URL.newsID>
...
</cfif>

Why it’s bad: No match when there were no pound signs (ie Script/logic not output)

Iteration 3

Third time is a charm!

Search: \bHash\(\s*([^,\)\r\n]+?)\s*\)
Replace: Hash($1, "SHA-256", "UTF-8")

cfhash search and replace regex
cfhash search and replace with regex vscode screenshot

Conclusion

YAY! This result yielded 206 corrections throughout the app that would have taken a long time to correct without a REGEX search and replace. This legacy app is 20+ years old so the first goal was compatibility. In a follow up article I’ll look at improving security with HMAC.

Note

This post was amended from “the default hashing algorithm changed from MD5 to SHA-256” to “the default hashing algorithm changed from CFMX_COMPAT to SHA-256”. Even though they do the same thing the default was technically CFMX_COMPAT.

2 thoughts on “ColdFusion Hash() Defaults Changed — Here’s How to Fix It With Regex”

  1. Thanks for sharing! (Your blog post showed up on the CFBreak newsletter.)

    The default has been changed again? It was initially “CFMX_COMPAT” before it changed to “MD5”.

    I’m so glad that I used File Locator Pro during the first change, identified all internal CFM templates, custom tags, CFC and third-party libraries to ensure that “MD5” was explicitly used. (ie, “Fool me once, shame on you”.)

    I have the ability to perform blind search-and-replace operations, but prefer to view the context in order to ensure that I’m not accidentally changing a javascript function that just happens to have similar syntax. (This has happened to me before.)

  2. I don’t think it changed again. MD5 and CFMX_COMPAT are the same thing. There’s a pretty extensive discussion of it here. In light of that discussion I am going to amend my post where I said “the default hashing algorithm changed from MD5 to SHA-256″ to “the default hashing algorithm changed from CFMX_COMPAT to SHA-256″ since that was the actual change.

    Why this post is coming almost 20 months after the update is because a legacy application that I support is soon migrating to ColdFusion 2025. The “fix” that was done back when the ColdFusion 2021 Update 14 came out (06/11/2024) was to apply the jvm flag:

    -Dcoldfusion.encryption.useCFMX_COMPATAsDefault

    to tell ColdFusion to keep using CFMX_COMPAT (same as MD5) as the default. In ColdFusion 2025 that flag is removed so if you don’t want to use SHA-256 you must supply the algorithm argument.

    I just recently started using **/js/** in the “files to exclude” box under the VSCode search/replace to exclude our javascript files from the results. Also, for context I found the Open in editor link above the results will show all of the results in the editor window with the line prior to the match and the line after. Searching for “f_comment()” yields something like:

    VScode Search Replace Context

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.