CFHTTP and SSL issues with CommandBox 5
We recently ran into a puzzling issue with
cfhttp and CommandBox 5. Requests to certain domains, such as trycf.com, would fail with
Unknown host: Received fatal alert: handshake_failure, despite the domain's SSL certificate being valid. I hope this post, which digs into the somewhat unexpected source of them problem, is helpful to anyone else who might encounter the error.
tldr; Try adding the Runwar arg
--ssl-eccdisable=false to your
server.json file to resolve
cfhttp connection issues.
cfhttp requests worked as expected, we found our application unable to make requests to certain domains - a problem first, because one of the domains was a geocoding API we used, and second, because we didn't know why it was happening.
We took detours down a few rabbit holes, trying different versions of Java and tweaking a host of JVM args, but nothing worked; everything came back with an SSL handshake error.
Finally, we discovered that when our app had SSL enabled in
cfhttp requests would fail. If we disabled SSL, the requests would be completed successfully.
Update - 06/05/2020: A patch in CommandBox 5.1.1 resolved the issue that lead to this post for Lucee servers, though I believe that servers started with Adobe ColdFusion still experience it.
The Runwar Argument
Brad Wood, wizard of CommandBox that he is, responded to the ticket, asking me to try adding the following Runwar argument:
--ssl-eccdisable=false. Sure enough, with that flag added, the formerly failing
cfhttp requests worked, both with and without SSL enabled.
Here's what the flag looks like in a
However, there's a bit more to the equation, because the way your application responds to this argument depends on the ColdFusion engine (Adobe, Lucee), the particular version, and the version of Java being used. And the results vary considerably - more on this at the end.
Why the Runwar Argument is Needed
It turns out that earlier versions of Adobe ColdFusion, running via CommandBox, had issues serving SSL certificates, unless they were started with the JVM arg:
ECC stands for Elliptic Curve Cryptography, but I'm not going to pretend that I understand it any more than that.
The bottom line is that by disabling this ECC option, ColdFusion/CommandBox could serve SSL certificates without issue. Consequently, the flag disabling ECC got baked into CommandBox as a default and is applied when starting a server with SSL enabled. In an earlier version of Runwar that was used with CommandBox 4.8, this flag was only applied to Adobe ColdFusion servers, but because of how things were refactored, it now appears to be used across the board.
None of this mattered all that much, because there were no known negative side effects of passing in this option.
Considerations and Negative Side Effects
It turns out that enabling/disabling the ECC flag impacts not just how your application serves SSL, but also how it interacts with SSL certificates on other websites. For some current SSL certificates, disabling ECC renders ColdFusion unable to negotiate an SSL connection when making a
cfhttp request. The flag Brad provided overrides the CommandBox default, so the ECC option remains enabled, and ColdFusion can complete the
cfhttp request successfully.
Unfortunately, you can't just blindly implement
--ssl-eccdisable=false. If you have SSL enabled and are running Adobe ColdFusion 11, this option will prevent your app from loading because of an SSL protocol error. The same holds true for Adobe ColdFusion 2016, if you're running Java 8, though the protocol error is resolved if you're running Java 11.
That said, if you have SSL enabled and you're running any version of Lucee 5 or Adobe ColdFusion 2018, based on my limited testing, you'll likely want to configure your servers with
--ssl-eccdisable=false, to ensure the widest range of successful
cfhttp interactions with SSL certificates.
The table here should the results of my testing. The Runwar Arg column indicates if the server was started with the
--ssl-eccdisable=false flag. If the SSL connection was valid, I made
cfhttp requests to both https://trycf.com and https://google.com. Hopefully you find this helpful.
That said, there is no substitute for testing your own apps.
|Engine||Version||Java||Runwar Arg||SSL Connection||trycf.com||google.com|
|Lucee||5.3.6||11||Yes||Valid||200 OK||200 OK|
|Lucee||5.2.9||8||Yes||Valid||200 OK||200 OK|
|Lucee||5.2.9||11||Yes||Valid||200 OK||200 OK|
|Adobe||2018||8||Yes||Valid||200 OK||200 OK|
|Adobe||2018||11||Yes||Valid||200 OK||200 OK|
|Adobe||2016||11||Yes||Valid||200 OK||200 OK|
Specific versions used for testing
- Adobe Coldfusion 2018.0.9+318650
- Adobe ColdFusion 2016.0.15+318650
- Adobe ColdFusion 11.0.19+314546
- Lucee 5.3.6+61
- Lucee 5.2.9+31
- Java (OpenJDK) 11_jdk-11.0.6+10
- Java (OpenJDK) 8_jdk8u252-b09.1
One commonality in the websites that we were unable to connect to was that their certificates were issued by Cloudflare. For example: https://trycf.com, https://geocoder.ca, and https://jsonplaceholder.typicode.com ↩︎