So I keep getting “Missing X-content-type-options ...
# questions
d
So I keep getting “Missing X-content-type-options header” on vulnerability scans. So I added “nosniff” to the headers in an interceptor. The issue is, the scan is showing the issue on /assets/js file. So if I do something like localhost:8080/assets/jsfile I am not getting the nosniff header. I was wondering if there is a way to configure the tomcat server itself in something like the application.yml file to add no sniff? Or if there is another way to get that header?
j
Use a filter - the asset plugin is implemented with filters so its invoking before you interceptor
d
@jdaugherty could you give me an example of how to do this? I’m not seeing much online on how to implement filters.
j
Its a servlet filter; asset pipeline ships with one if you look at its code base
d
@jdaugherty So in grails-app/spring/resource.groovy I made a nosniffFilter, and that successfully added nosniff to all the responses, except the static assets. So when go to application.groovy and put the following code, it still is not working. Do you know what I am doing wrong?
Copy code
grails {
    springsecurity {
        filterChain {
        chainMap = [
            [pattern:'/assets/**', filters:'nosniffFilter']
        ]
        }
    }
}
j
the asset pipeline registers a filter that triggers before the spring security one and the filters inside of spring security are specific to security. To register a filter, you use the FilterRegistrationBean to set the order. In my case, I actually extend the asset plugin and secure certain assets. To register, you define a bean first:
``` Map assetsConfig = grailsApplication.config.getProperty('grails.assets', Map, [:])
def mapping = assetsConfig.containsKey('mapping') ? assetsConfig.mapping?.toString() : 'assets'
assetPipelineFilter(FilterRegistrationBean<SecuredAssetPipelineFilter>) {
order = 101
filter = new SecuredAssetPipelineFilter()
if(!mapping) {
urlPatterns = ["/*".toString()]
} else {
urlPatterns = ["/${mapping}/*".toString()]
}
}```
In my case, I override the asset pipeline filter to secure assets:
```class SecuredAssetPipelineFilter extends AssetPipelineFilter {
@Override
void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException, ServletException {
boolean wasCommitted = response.committed
super.doFilterInternal(request, response, chain)
if(!wasCommitted && response.committed) { //Reset the flash scope
GrailsWebRequest webRequest = WebUtils.retrieveGrailsWebRequest()
if(!webRequest) {
throw new IllegalStateException("Could not locate Grails Web Request.")
}
FlashScope flash = webRequest.getAttributes().getFlashScope(request)
flash.putAll(flash.now)
}
}
}```
They key thing is: 1. register your filter 2. make sure that registration order is before the security one 3. you can then change the request anyway you want