Skip to content

KNOX-3124 - Add Security Header filter to WebAppSec Provider #1021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

lmccay
Copy link
Contributor

@lmccay lmccay commented Apr 10, 2025

What changes were proposed in this pull request?

In order to add various security headers to a response, we can add a generic filter for which init params with the param name and value indicating the header name and string representing the directives for the header respectively.

This will allow admins to configure things like Content-Security-Policy, Cache-Control, etc. without the need to add separate filters for each one.

How was this patch tested?

New unit tests were added.
All new and existing tests were run.
Manual testing was done with the following web app sec provider config and curl command:

      <provider>
         <role>webappsec</role>
         <name>WebAppSec</name>
         <enabled>true</enabled>
         <param>
            <name>csrf.customHeader</name>
            <value>X-XSRF-Header</value>
         </param>
         <param>
            <name>csrf.methodsToIgnore</name>
            <value>GET,OPTIONS,HEAD</value>
         </param>
         <param>
            <name>xframe.options.enabled</name>
            <value>true</value>
         </param>
         <param>
            <name>xss.protection.enabled</name>
            <value>true</value>
         </param>
         <param>
            <name>strict.transport.enabled</name>
            <value>true</value>
         </param>
         <param>
            <name>xframe.options</name>
            <value>SAMEORIGIN</value>
         </param>
         <param>
            <name>security.header.enabled</name>
            <value>true</value>
         </param>
         <param>
            <name>security.header.Content-Security-Policy</name>
            <value>default-src 'self'</value>
         </param>
         <param>
            <name>security.header.Cache-Control</name>
            <value>max-age=604800</value>
         </param>
      </provider>

Note the params with the "security.header." prefix and the headers added to the resulting output from the curl command below:

curl -ivku admin:admin-password -X POST "https://localhost:8443/gateway/sandbox/clientid/api/v1/oauth/credentials"

< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Thu, 10 Apr 2025 12:03:04 GMT
Date: Thu, 10 Apr 2025 12:03:04 GMT
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1;mode=block
X-XSS-Protection: 1;mode=block
< Strict-Transport-Security: max-age=31536000
Strict-Transport-Security: max-age=31536000
**< Cache-Control: max-age=604800
Cache-Control: max-age=604800
< Content-Security-Policy: default-src 'self'
Content-Security-Policy: default-src 'self'**
< pattern: clientid/api/**?**
pattern: clientid/api/**?**
< Set-Cookie: KNOXSESSIONID=node0oggzblclwhrm1u6i6xsx4xn33.node0; Path=/gateway/sandbox; Secure; HttpOnly
Set-Cookie: KNOXSESSIONID=node0oggzblclwhrm1u6i6xsx4xn33.node0; Path=/gateway/sandbox; Secure; HttpOnly
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Set-Cookie: rememberMe=deleteMe; Path=/gateway/sandbox; Max-Age=0; Expires=Wed, 09-Apr-2025 12:03:04 GMT; SameSite=lax
Set-Cookie: rememberMe=deleteMe; Path=/gateway/sandbox; Max-Age=0; Expires=Wed, 09-Apr-2025 12:03:04 GMT; SameSite=lax
< Content-Type: application/json
Content-Type: application/json
< Content-Length: 203
Content-Length: 203
< 

@lmccay lmccay requested review from moresandeep and pzampino April 10, 2025 17:56
@@ -55,6 +55,10 @@ public class WebAppSecContributor extends ProviderDeploymentContributorBase {
private static final String RATE_LIMITING_PREFIX = "rate.limiting";
private static final String RATE_LIMITING_SUFFIX = "_RATE.LIMITING";
private static final String RATE_LIMITING_ENABLED = RATE_LIMITING_PREFIX + ".enabled";
private static final String SECURITY_HEADER_PREFIX = "security.header";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the prefix should be "security.header." (note the . at the end).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree but others are this way too just keeping it consistent.


public class SecurityHeaderFilter implements Filter {

private Map<String, String> map = new HashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better class member name would be more helpful.

Enumeration<String> initParamNames = filterConfig.getInitParameterNames();
while (initParamNames.hasMoreElements()) {
String headerName = initParamNames.nextElement();
if (!"enabled".equals(headerName)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to create another constant for enabled in WebAppSeciContributor and re-use it here.


@Override
public void addHeader(String name, String value) {
if (!"enabled".equals(name)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my recommendation above of using a constant here.

Copy link
Contributor

@pzampino pzampino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants