Skip to content

Commit efec77b

Browse files
authored
Merge pull request #14 from homestar9/patch-1
Don't trigger ColdBox's invalid event looping protection
2 parents cf50b23 + 95e3d94 commit efec77b

File tree

2 files changed

+81
-6
lines changed

2 files changed

+81
-6
lines changed

interceptors/Security.cfc

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/**
22
* Copyright since 2016 by Ortus Solutions, Corp
33
* www.ortussolutions.com
44
* ---
@@ -12,6 +12,7 @@ component accessors="true" extends="coldbox.system.Interceptor" {
1212
property name="rulesLoader" inject="rulesLoader@cbSecurity";
1313
property name="handlerService" inject="coldbox:handlerService";
1414
property name="cbSecurity" inject="@cbSecurity";
15+
property name="invalidEventHandler" inject="coldbox:setting:invalidEventHandler";
1516

1617
/**
1718
* The reference to the security validator for this interceptor
@@ -27,6 +28,11 @@ component accessors="true" extends="coldbox.system.Interceptor" {
2728
* Configure the security firewall
2829
*/
2930
function configure(){
31+
variables.onInvalidEventHandlerBean = javacast( "null", "" );
32+
if ( len( variables.invalidEventHandler ) ) {
33+
variables.onInvalidEventHandlerBean = handlerService.getHandlerBean( variables.invalidEventHandler );
34+
}
35+
3036
// init the security modules dictionary
3137
variables.securityModules = {};
3238

@@ -45,6 +51,9 @@ component accessors="true" extends="coldbox.system.Interceptor" {
4551

4652
// Load up the validator
4753
registerValidator( getInstance( getProperty( "validator" ) ) );
54+
55+
// Coldbox version 5 (and lower) needs a little extra invalid event handler checking.
56+
variables.enableInvalidHandlerCheck = ( listGetAt( controller.getColdboxSettings().version, 1, "." ) <= 5 );
4857
}
4958

5059
/**
@@ -223,7 +232,27 @@ component accessors="true" extends="coldbox.system.Interceptor" {
223232
required currentEvent
224233
){
225234
// Get handler bean for the current event
226-
var handlerBean = variables.handlerService.getHandlerBean( arguments.event.getCurrentEvent() );
235+
var handlerBean = variables.handlerService.getHandlerBean( arguments.event.getCurrentEvent() );
236+
237+
// Are we running Coldbox 5 or older?
238+
// is an onInvalidHandlerBean configured?
239+
// is the current handlerBean the configured onInvalidEventHandlerBean?
240+
if (
241+
variables.enableInvalidHandlerCheck &&
242+
!isNull( variables.onInvalidEventHandlerBean ) &&
243+
isInvalidEventHandlerBean( handlerBean )
244+
) {
245+
// ColdBox tries to detect invalid event handler loops by keeping
246+
// track of the last invalid event to fire. If that invalid event
247+
// fires twice, it throws a hard exception to prevent infinite loops.
248+
// Unfortunately for us, just attempting to get a handler bean
249+
// starts the invalid event handling. Here, if we got the invalid
250+
// event handler bean back, we reset the `_lastInvalidEvent` so
251+
// ColdBox can handle the invalid event properly.
252+
request._lastInvalidEvent = variables.invalidEventHandler;
253+
return;
254+
}
255+
227256
if ( handlerBean.getHandler() == "" ) {
228257
return;
229258
}
@@ -704,5 +733,19 @@ component accessors="true" extends="coldbox.system.Interceptor" {
704733

705734
return len( CGI.REMOTE_ADDR ) ? CGI.REMOTE_ADDR : "127.0.0.1";
706735
}
736+
737+
/**
738+
* Returns true of the passed handlerBean matches Coldbox's configured invalid event handler.
739+
*
740+
* @handlerBean the current handler bean to check against
741+
*/
742+
private boolean function isInvalidEventHandlerBean( required handlerBean ) {
743+
return (
744+
variables.onInvalidEventHandlerBean.getInvocationPath() == arguments.handlerBean.getInvocationPath() &&
745+
variables.onInvalidEventHandlerBean.getHandler() == arguments.handlerBean.getHandler() &&
746+
variables.onInvalidEventHandlerBean.getMethod() == arguments.handlerBean.getMethod() &&
747+
variables.onInvalidEventHandlerBean.getModule() == arguments.handlerBean.getModule()
748+
);
749+
}
707750

708751
}

test-harness/tests/specs/unit/SecurityTest.cfc

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ component extends="coldbox.system.testing.BaseInterceptorTest" interceptor="cbse
1313
// setup properties
1414
setup();
1515
variables.wirebox = new coldbox.system.ioc.Injector();
16-
mockController.$( "getAppHash", hash( "appHash" ) ).$( "getAppRootPath", expandPath( "/root" ) );
17-
security = interceptor;
16+
mockController
17+
.$( "getAppHash", hash( "appHash" ) )
18+
.$( "getAppRootPath", expandPath( "/root" ) )
19+
.$( "getColdboxSettings", {
20+
"version": "6.0.0"
21+
}, false );
22+
security = interceptor;
23+
security.setInvalidEventHandler( '' );
1824
settings = {
1925
// The global invalid authentication event or URI or URL to go if an invalid authentication occurs
2026
"invalidAuthenticationEvent" : "",
@@ -131,7 +137,32 @@ component extends="coldbox.system.testing.BaseInterceptorTest" interceptor="cbse
131137
expect( function(){
132138
security.configure();
133139
} ).toThrow( "Security.ValidatorMethodException" );
134-
} );
140+
} );
141+
142+
it( "does not enable invalid event handler processing on Coldbox versions 6+", function() {
143+
security.setProperties( settings );
144+
security
145+
.$( "getInstance" )
146+
.$args( settings.validator )
147+
.$results( wirebox.getInstance( settings.validator ) );
148+
security.configure();
149+
expect( security.$getProperty( "enableInvalidHandlerCheck" ) ).toBeFalse();
150+
} );
151+
152+
it( "enables invalid event handler processing on Coldbox versions prior to 6", function() {
153+
154+
mockController.$( "getColdboxSettings", {
155+
"version": "5.0.0"
156+
}, false );
157+
158+
security.setProperties( settings );
159+
security
160+
.$( "getInstance" )
161+
.$args( settings.validator )
162+
.$results( wirebox.getInstance( settings.validator ) );
163+
security.configure();
164+
expect( security.$getProperty( "enableInvalidHandlerCheck" ) ).toBeTrue();
165+
} );
135166

136167
describe( "It can load many types of rules", function(){
137168
beforeEach( function(currentSpec){
@@ -173,7 +204,8 @@ component extends="coldbox.system.testing.BaseInterceptorTest" interceptor="cbse
173204

174205
expect( security.getProperty( "rules", [] ) ).toHaveLength( 1 );
175206
} );
176-
} );
207+
} );
208+
177209
} );
178210
}
179211

0 commit comments

Comments
 (0)