Forum Discussion
ASM Bot Defense JS and CSP
Our company has issued a requirement for all applications to enable CSP (Content Security Policy). The problem is one of the first applications to enable this has Bot Defense enabled. Part of PBD is to inject a JAVA script inline which causes an issue with the page not loading per the CSP policy. We opened a support case and F5 level II and the ENE say they can't find a way to make these compatible and this is beyond the scope of Support i.e. engage Professional Services. I'm a long-time F5 user and so this was frustrating, to say the least.
Part of our CSP is our scripts have a nonce key generated. PBD script is not being delivered from our server (it's directly injected into the response), and it does not contain our nonce key. This means that the CSP will tell the browser to NOT allow the execution of that script thereby breaking the application.
Part of the CSP Rules
- The browser should accept any JS that is delivered as a file from 'self' which means it's delivered from our web server with a relative path
- The browser should accept any JS that is delivered to the browser with our nonce key (value in the header)
- All other JS should be ignored by the browser!
So, the only question that we really had for F5 is how do we make PBD JS work with a CSP? The CSP is set up in a basic way and is not customized to our application at all. It seems we either need to have this JS delivered by a file (not directly injected) or the F5 will need to pick up our nonce key and add it to that injection.
Has anyone come across this and what methods did you employ to resolve it, i.e. iRule or Traffic policy to set the nonce key on the JS, which is not super ideal?
Depending on when ASM/PBD fire, something similar to the following:
when HTTP_RESPONSE {
# Check if the response header contains a CSP
if {[HTTP::header exists "Content-Security-Policy"]} {
# Get the CSP header value
set csp [HTTP::header value "Content-Security-Policy"]
# Check if the CSP contains a nonce
if {[string first "nonce-" $csp] != -1} {
# Get the nonce value
set nonce [string range $csp [string first "nonce-" $csp] [string first ";" $csp]]
# Check if the response body contains a script tag
if {[string first "<script" [HTTP::payload]] != -1} {
# Add the nonce to the script tag
HTTP::payload replace [string first "<script" [HTTP::payload]] [string first ">" [HTTP::payload]] "<script nonce=\"$nonce\""
}
}
}
}
- jayantandAltostratus
I have faced the same issue...the JS broke the application. Running Bot Defense without features that send ASM proactive cookies (not the ideal solution!).
- rburchNimbostratus
Was there any resolution for this issue as I am running into this issue myself?
- JklarenNimbostratus
Has anyone come across this and what methods did you employ to resolve it, i.e. iRule or Traffic policy to set the nonce key on the JS, which is not super ideal?
I am running into the same issue here.
Have just tested this but the issue is that ASM sets the script tags in the http payload after the HTTP_RESPONSE_DATA event, this is the last moment we can manipulate the payload. So we are never able to manipulate the script tags ourself to add the nonce value.
UPDATE:
I have created an irule that works for me. It uses a HTML profile with a rule that triggers on seeing a script tag in the HTML. When using this profile you get access to the HTML_TAG_MATCHED even in the irule.
The irule then takes the nonce value from the content security profile an adds it (if missing) to the script tags.
I shared it on GitHub as well.
https://github.com/security-by-design-it/F5-Irules/blob/main/set_nonce_js_inject.tcl
# IRule to get the nonce value of a CSP header and put it in the HTML script tags # This is needed for the JavaScript that is injected by an ASM Bot Defence profile # Make sure to put a HTML profile on the virtual server that triggers an # event when it detects a script-tag in the HTML. when HTTP_RESPONSE { # Check if the response header contains a CSP if {[HTTP::header exists "Content-Security-Policy"]} { # Get the CSP header value set csp [HTTP::header value "Content-Security-Policy"] # Check if the CSP contains a nonce if {[string first "nonce-" $csp] != -1} { # Get the nonce value set idx [string first "nonce-" $csp] set nonce [string trim [string range $csp $idx end-3] "nonce-"] } } } # Event if the HTML profile rule is triggered when HTML_TAG_MATCHED { # Check if nonce value allready exists, if not add it if {not [HTML::tag attribute exists "nonce"]} { HTML::tag attribute insert "nonce" $nonce } }
This is the HTML Profile event rule i created, you link this to a HTML profile then you add it in your virtual server config.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com