@@ -82,7 +82,6 @@ public class WAFModule implements AppSecModule {
8282 private static final Map <String , ActionInfo > DEFAULT_ACTIONS ;
8383
8484 private static final String EXPLOIT_DETECTED_MSG = "Exploit detected" ;
85- private WafHandle wafHandle ;
8685 private boolean init = true ;
8786 private String rulesetVersion ;
8887 private WafBuilder wafBuilder ;
@@ -99,9 +98,11 @@ private ActionInfo(String type, Map<String, Object> parameters) {
9998
10099 private static class CtxAndAddresses {
101100 final Collection <Address <?>> addressesOfInterest ;
101+ final WafHandle ctx ;
102102
103- private CtxAndAddresses (Collection <Address <?>> addressesOfInterest ) {
103+ private CtxAndAddresses (Collection <Address <?>> addressesOfInterest , WafHandle ctx ) {
104104 this .addressesOfInterest = addressesOfInterest ;
105+ this .ctx = ctx ;
105106 }
106107 }
107108
@@ -137,6 +138,8 @@ static void createLimitsObject() {
137138 Config .get ().getAppSecWafTimeout ());
138139 }
139140
141+ private final boolean wafMetricsEnabled =
142+ Config .get ().isAppSecWafMetrics (); // could be static if not for tests
140143 private final AtomicReference <CtxAndAddresses > ctxAndAddresses = new AtomicReference <>();
141144 private final RateLimiter rateLimiter ;
142145
@@ -197,24 +200,27 @@ private void applyConfig(AppSecModuleConfigurer.Reconfiguration reconf)
197200
198201 private void initOrUpdateWafHandle (AppSecModuleConfigurer .Reconfiguration reconf )
199202 throws AppSecModuleActivationException {
200- WafHandle oldHandle = wafHandle ;
203+ CtxAndAddresses prevContextAndAddresses = this .ctxAndAddresses .get ();
204+ WafHandle newHandle ;
201205 try {
202- wafHandle = wafBuilder .buildWafHandleInstance ();
203- reconf .reloadSubscriptions ();
206+ newHandle = wafBuilder .buildWafHandleInstance ();
204207 } catch (AbstractWafException e ) {
205- log .info ("Could not initialize waf handle, no rules were added!" , e );
206208 throw new AppSecModuleActivationException (
207209 "Could not initialize waf handle, no rules were added!" , e );
208- } finally {
209- if (oldHandle != null && oldHandle .isOnline ()) {
210- oldHandle .close ();
211- }
212210 }
213211
214- CtxAndAddresses newContextAndAddresses = new CtxAndAddresses (getUsedAddresses (wafHandle ));
215- if (!this .ctxAndAddresses .compareAndSet (ctxAndAddresses .get (), newContextAndAddresses )) {
212+ Collection <Address <?>> addresses = getUsedAddresses (newHandle );
213+ CtxAndAddresses newContextAndAddresses = new CtxAndAddresses (addresses , newHandle );
214+ if (!this .ctxAndAddresses .compareAndSet (prevContextAndAddresses , newContextAndAddresses )) {
215+ newHandle .close ();
216216 throw new AppSecModuleActivationException ("Concurrent update of WAF configuration" );
217217 }
218+
219+ if (prevContextAndAddresses != null ) {
220+ prevContextAndAddresses .ctx .close ();
221+ }
222+
223+ reconf .reloadSubscriptions ();
218224 }
219225
220226 private static RateLimiter getRateLimiter (Monitoring monitoring ) {
@@ -289,13 +295,19 @@ public void onDataAvailable(
289295 DataBundle newData ,
290296 GatewayContext gwCtx ) {
291297 Waf .ResultWithData resultWithData ;
298+ CtxAndAddresses ctxAndAddr = ctxAndAddresses .get ();
299+ if (ctxAndAddr == null ) {
300+ log .debug ("Skipped; the WAF is not configured" );
301+ return ;
302+ }
292303 if (reqCtx .isWafContextClosed ()) {
293304 log .debug ("Skipped; the WAF context is closed" );
294305 if (gwCtx .isRasp ) {
295306 WafMetricCollector .get ().raspRuleSkipped (gwCtx .raspRuleType );
296307 }
297308 return ;
298309 }
310+
299311 StandardizedLogging .executingWAF (log );
300312 long start = 0L ;
301313 if (log .isDebugEnabled ()) {
@@ -307,7 +319,7 @@ public void onDataAvailable(
307319 }
308320
309321 try {
310- resultWithData = doRunWaf (reqCtx , newData , gwCtx );
322+ resultWithData = doRunWaf (reqCtx , newData , ctxAndAddr , gwCtx );
311323 } catch (TimeoutWafException tpe ) {
312324 if (gwCtx .isRasp ) {
313325 reqCtx .increaseRaspTimeouts ();
@@ -497,8 +509,13 @@ private StackTraceEvent createExploitStackTraceEvent(String stackId) {
497509 }
498510
499511 private Waf .ResultWithData doRunWaf (
500- AppSecRequestContext reqCtx , DataBundle newData , GatewayContext gwCtx )
512+ AppSecRequestContext reqCtx ,
513+ DataBundle newData ,
514+ CtxAndAddresses ctxAndAddr ,
515+ GatewayContext gwCtx )
501516 throws AbstractWafException {
517+ WafContext wafContext =
518+ reqCtx .getOrCreateWafContext (ctxAndAddr .ctx , wafMetricsEnabled , gwCtx .isRasp );
502519 WafMetrics metrics ;
503520 if (gwCtx .isRasp ) {
504521 metrics = reqCtx .getRaspMetrics ();
@@ -508,18 +525,17 @@ private Waf.ResultWithData doRunWaf(
508525 }
509526
510527 if (gwCtx .isTransient ) {
511- return runWafTransient (
512- reqCtx .getOrCreateWafContext (wafHandle , gwCtx .isRasp ), metrics , newData );
528+ return runWafTransient (wafContext , metrics , newData , ctxAndAddr );
513529 } else {
514- return runWafContext (
515- reqCtx .getOrCreateWafContext (wafHandle , gwCtx .isRasp ), metrics , newData );
530+ return runWafContext (wafContext , metrics , newData , ctxAndAddr );
516531 }
517532 }
518533
519534 private Waf .ResultWithData runWafContext (
520- WafContext wafContext , WafMetrics metrics , DataBundle newData ) throws AbstractWafException {
535+ WafContext wafContext , WafMetrics metrics , DataBundle newData , CtxAndAddresses ctxAndAddr )
536+ throws AbstractWafException {
521537 return wafContext .run (
522- new DataBundleMapWrapper (getUsedAddresses ( wafHandle ) , newData ), LIMITS , metrics );
538+ new DataBundleMapWrapper (ctxAndAddr . addressesOfInterest , newData ), LIMITS , metrics );
523539 }
524540 }
525541
@@ -534,9 +550,10 @@ private static void incrementErrorCodeMetric(
534550 }
535551
536552 private Waf .ResultWithData runWafTransient (
537- WafContext wafContext , WafMetrics metrics , DataBundle newData ) throws AbstractWafException {
553+ WafContext wafContext , WafMetrics metrics , DataBundle newData , CtxAndAddresses ctxAndAddr )
554+ throws AbstractWafException {
538555 return wafContext .runEphemeral (
539- new DataBundleMapWrapper (getUsedAddresses ( wafHandle ) , newData ), LIMITS , metrics );
556+ new DataBundleMapWrapper (ctxAndAddr . addressesOfInterest , newData ), LIMITS , metrics );
540557 }
541558
542559 private Collection <AppSecEvent > buildEvents (Waf .ResultWithData actionWithData ) {
0 commit comments