Blog

Brad Wood

December 08, 2020

Spread the word


Share your thoughts

CommandBox 5.2.0 added a new feature called Server Profiles which allow you to dial in a bevy of development or production lockdown rules in a single setting.  Each profile can be tweaked with individual settings to customize them.

https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/server-profiles#customizing-your-profile

{
  "profile": "production"
  "web": {
    "blockCFAdmin": false
  }
}

Override parts of a default lockdown

However, what if you want to go one step deeper?  For instance, the "blockSensitivePaths" setting blocks a whole bunch of stuff all in one shot.  Turning on web.blockSensitivePaths is the same as adding all of these individual rules:

// track and trace verbs can leak data in XSS attacks
"disallowed-methods( methods={trace,track} )",
// Common config files and sensitive paths in ACF and TestBox
"regex( pattern='.*/(box.json|server.json|web.config|urlrewrite.xml|package.json|package-lock.json|Gulpfile.js|CFIDE/multiservermonitor-access-policy.xml|CFIDE/probe.cfm|CFIDE/main/ide.cfm|tests/runner.cfm|testbox/system/runners/HTMLRunner.cfm)', case-sensitive=false ) -> { set-error(404); done }",
// Any file or folder starting with a period
"regex('/\.') -> { set-error( 404 ); done }",
// Additional serlvlet mappings in Adobe CF's web.xml
"path-prefix( { '/JSDebugServlet','/securityanalyzer','/WSRPProducer' } ) -> { set-error( 404 ); done }",
// java web service (Axis) files
"regex( pattern='\.jws$', case-sensitive=false ) -> { set-error( 404 ); done }"

I had a question from a client today who wants to keep the blockSensitivePaths setting active for his servers, but also wanted to open up JUST the RDS IDE integration for his developers, which funnels through the /CFIDE/main/ide.cfm path which you can see is blocked above.

Order of Server Rule Execution

The solution to this is quite simple and is all based on the ORDER in which your rules are processed as documented here:

https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/server-rules#create-your-rules

  1. Ad-hoc rule array in server.json
  2. External rules files in server.json in the order defined
  3. Ad-hoc rule array in config setting server.defaults
  4. External rules files in config setting server.defaults in the order defined
  5. CommandBox built-in rules (web.blockCFAdmin, web.blockConfigPaths)
  6. Any module listening to server interceptions can inject their rules wherever they please in the array.

You can see that the built-in CommadBox rules are the last to process.  This means that if you highjack the predicates with a custom rule FIRST, you can override the behavior of the built in rules. 

Add a Custom Server Rule

So, if we want to allow access to the /CFIDE/main/ide.cfm path, we just need to add a custom rule that matches that path and then aborts the predicate chain so no further rules fire.  

server set web.rules="['path(/CFIDE/main/ide.cfm)->done']" --append

Which gives you the following server.json

{
    "web":{
        "rules":[
            "path(/CFIDE/main/ide.cfm)->done"
        ]
    }
}

The "done" handler is what bypasses all subsequent rules for the request.  Read more about how server rules work here:

https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/server-rules/rule-language

And a fair warning-- since your custom rules are processed BEFORE the built-in rules, that also means that you have the ability to accidentally bypass security rules by applying another rule that intercepts the request.  By default a custom rule won't block subsequent rules from firing unless you rewrite the request or use the special "done" handler.

Debugging Server Rules

And to test/debug your rules, start your server with the trace flag and tail the console output.  Every hit in your browser will output several lines of debugging for each rule that is processed.

server start --trace --console

With the custom rule above, you'd see something like this:

[DEBUG] requested: '/CFIDE/main/ide.cfm'
[TRACE] io.undertow.predicate: Path(s) [/CFIDE/main/ide.cfm] MATCH input [/CFIDE/main/ide.cfm] for HttpServerExchange{ GET /CFIDE/main/ide.cfm}.
[TRACE] io.undertow.predicate: Predicate [path( '/CFIDE/main/ide.cfm' )] resolved to true. Next handler is [done] for HttpServerExchange{ GET /CFIDE/main/ide.cfm}.
[TRACE] io.undertow.predicate: Predicate chain marked done. Next handler is [Runwar PathHandler] for HttpServerExchange{ GET /CFIDE/main/ide.cfm}.
[WARN ] responded: Status Code 200 (/CFIDE/main/ide.cfm)

 

Add Your Comment

Recent Entries

The Hidden Costs of In-House Database Management

The Hidden Costs of In-House Database Management

The Hidden Costs of In-House Database Management


Opting for in-house database management involves more than just a salary. Here are some often-overlooked costs associated with maintaining your own DBA team.



1. High Salaries and Benefits


Hiring skilled DBAs is expensive. According to industry reports, the average salary of a DBA in the U.S. can range from $85,000 to over $130,000 per year, depending on experience and expertise. When you add ...

Cristobal Escobar
Cristobal Escobar
November 20, 2024
5 Signs It’s Time to Modernize Your ColdFusion / CFML Application

5 Signs It’s Time to Modernize Your ColdFusion / CFML Application

ColdFusion has long been a reliable platform for building web applications, but like any technology, it requires maintenance and modernization over time. Whether you're using Lucee or Adobe ColdFusion, it’s critical to recognize the signs that your application is no longer meeting today’s standards in performance, security, and scalability. Let’s explore five clear indicators that it’s time to modernize your ColdFusion application and how ColdFusion consulting can help breathe new life into y...

Cristobal Escobar
Cristobal Escobar
November 19, 2024
ColdBox Free Tip 5 - Building Named Routes with a Struct

ColdBox Free Tip 5 - Building Named Routes with a Struct

**Did you know ColdBox provides flexible ways to build routes using structs?** In this tip, we’ll cover how to use the `event.buildLink()` and `event.route()` methods for named routes, a feature that’s especially handy when working with dynamic URLs.

Maria Jose Herrera
Maria Jose Herrera
November 19, 2024