Tuning Content-Security-Policy for React apps

Hi,

I deployed a React app (backend) fronted by the MicroGateway.

The web console in the browser shows a lot of the following messages:

Content-Security-Policy: The page’s settings blocked an inline style (style-src-attr) from being applied because it violates the following directive: “default-src 'self'”

I read that the default policy is quite strict, so that’s understandable.

However, I was wondering about the steps to properly relax the policy.

  1. My first attempt would be to relax completely and just whitelist
  2. For second attempts, I might want to whitelist specific remote sources?

For (1), I configured HeaderRewrites with csp=false and linked this rewrite rule within the ContentSecurityPolicy CR.

---
apiVersion: microgateway.airlock.com/v1alpha1
kind: HeaderRewrites
metadata:
  name: kuard-header-rewrites
  namespace: airlock-gateway
spec:
  settings:
    operationalMode: Integration
  request:
    allow:
      # Allow all request headers, could also use matchingHeaders here
      allHeaders: {}
    add:
      custom:
        - name: Add test header
          headers:
            - name: x-header-modification
              value: test
          mode: OverwriteOrAdd
          requestConditions:
            path:
              matcher:
                prefix: /
  response:
    allow:
      # Allow all response headers.
      allHeaders: {}
    add:
      # BuiltIn allows configuring a set of predefined upstream response headers.
      # https://docs.airlock.com/microgateway/4.5/index/api/crds/header-rewrites/v1alpha1/#headerrewritesspecresponseaddbuiltin
      builtIn:
        # The CSP default configuration default-src 'self'; img-src * in the CR
        # HeaderRewrites is very strict and may have to be replaced by a custom
        # configuration.
        # https://docs.airlock.com/microgateway/4.5/index/1730261093172.html
        csp: false

I linked this rewrite rule with the CSP CR as follows:

---
apiVersion: microgateway.airlock.com/v1alpha1
kind: ContentSecurityPolicy
metadata:
  name: kuard
  namespace: airlock-gateway
spec:
  targetRefs:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: kuard
  secured:
    filter:
      denyRulesRef:
        name: kuard
      headerRewritesRef:
        name: kuard-header-rewrites

My React app in the background is kuard, an “echo server”.

The browser console still shows the error messages about the blocked/remote sources.

Which additional CRs do need tuning to (1) relax the setting completely for starters and (2) configure it for specific source (files)?

Thanks

Hi Andreas

Yes, the default policy (CSP header) is quite strict. The configuration you made looks fine so far. You disabled the CSP header, so CSP shouldn’t prevent the web application from working.

Do you have Grafana, Loki and Prometheus and our dashboards deployed? With our Grafana dashboards you should get quickly insights why something is blocked (if it was on the server side).

Do you see any problems in the browser console? Or do you see requests being blocked by Airlock Microgateway?

In case that Airlock Microgateway is blocking any requests, most likely the Limits are too low or the DenyRules filter are blocking. Simply configure these two filters for threatHandlingMode: LogOnly and see whether it’s working better (use this setting during integration and switch to threatHandlingMode: Block when you go into the production).

Try the following settings to relax your Limits and Deny Rules:

apiVersion: microgateway.airlock.com/v1alpha1
kind: Limits
metadata:
  name: kuard
spec: 
  settings: 
    threatHandlingMode: LogOnly
apiVersion: microgateway.airlock.com/v1alpha1
kind: DenyRules
metadata:
  name: kuard
spec: 
  request: 
    builtIn: 
      settings: 
        level: Standard
        threatHandlingMode: LogOnly

and refer the mentioned CRs in your ContentSecurityPolicy:

---
apiVersion: microgateway.airlock.com/v1alpha1
kind: ContentSecurityPolicy
metadata:
  name: kuard
  namespace: airlock-gateway
spec:
  targetRefs:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: kuard
  secured:
    filter:
      denyRulesRef:
        name: kuard
      headerRewritesRef:
        name: kuard-header-rewrites
      limitsRef:
        name: kuard

I hope this helps. Otherwise a remote session would be the easiest way to assist you.

Cheers
Stefan

1 Like

Hi @dieti

Thank you for the support. I will continue looking into the “Limits”.

It was a mistake in my config of the ContentSecurityPolicy.

I had the HeaderRewriteRule configured under ContentSecurityPolicy.spec.secured.filter.headerRewritesRef.

That config was not picked up, for good reason.

I needed to configure the headerRewritesRef under ContentSecurityPolicy.spec.secured.headerRewritesRef (not under “filter” key, such as for denyRulesRef!)

Sorry I missed that detail, but I’m sure the additional key (“filter”) is here for a reason.

Besides, I also switched to DenyRules level “Unfiltered” just to avoid troubles for now :slight_smile:

Thanks a lot.

Best,
Andreas

Hi Andreas

You are welcome. Great you found out why it wasn’t working.
Usually it’s very helpful to check the status of the Kubernetes resources to detect such errors. This means:

kubectl describe gatewayclasses.gateway.networking.k8s.io <Your-Gateway-Class-Resource>
kubectl describe gateways.gateway.networking.k8s.io <Your-Gateway>
kubectl describe httproutes.gateway.networking.k8s.io <Your-HTTP-Route>
kubectl describe contentsecuritypolicies.microgateway.airlock.com <Your-Content-Security-Policy>
kubectl describe accesscontrolpolicies.microgateway.airlock.com  <Your-Access-Control-Policy>

The Gateway API CRs reflect the status of Gateway API features. The two Microgateway CRs ContentSecurityPolicy and AccessControlPolicy reflect the status of the Microgateway features. Errors in CRs referenced in ContentSecurityPolicy or AccessControlPolicy (e.g. the Secret configured in the OIDCRelyingParty CR doesn’t exist) are populated.

I hope this helps to find such misconfiguration faster.

Cheers
Stefan