Content security policy

Hello all, I’m trying to find a way to pass the security team’s findings as a risk for my GitLab server. It is giving an error for “Content security policy” on the Sing_in page and is unable to fix this. Any help would be really nice as I’m stuck at this stage.

Thanks in advance!

Hi, you need to provide more information. You say it is giving an error, but you do not provide us with the error so we don’t know what it is. If we don’t know what it is, then it’s impossible to help :slight_smile:

Hi @colsol ,

I’m trying to find a way to pass the security team’s findings as a risk for my GitLab server. It is giving an error for “Content security policy”

It sounds like your security team ran a security scanner on your self-hosted GitLab instance and it reported that GitLab is not using a Content Security Policy. Now you’re investigating how to fix this or mitigate this finding. Is that correct?

If so, you’re seeing this because self-managed GitLab does not ship with a content security policy enabled by default, yet.

You can set a Content Security Policy on your self-managed GitLab instance by modifying your GitLab configuration: see GitLab Configuration Options > Set a Content Security Policy.
For GitLab Omnibus installations (Linux package or Docker Container Image), a CSP can be enabled and configured via gitlab.rb.

Note that Improperly configuring the CSP rules could prevent GitLab from working properly. It’s a good idea to change report_only to true to test the configuration before rolling out and enforcing a content security policy in production.

Once you have enabled a Content Security policy and verified that it works, security scans will no longer flag this as a security issue.

3 Likes

Thank you for your reply Greg. Yes, that’s correct and exactly what’s happening right now… I have tried to edit gitlab.rb file and added custom CSP value and saved but still having the same error on scans.

Can you show us what changes you made to gitlab.rb so we can see it?

For example on mine with default config:

gitlab_rails['content_security_policy'] = {
 'enabled' => true,
#  'report_only' => false,
#  # Each directive is a String (e.g. "'self'").
#  'directives' => {
#    'base_uri' => nil,
#    'child_src' => nil,
#    'connect_src' => nil,
#    'default_src' => nil,
#    'font_src' => nil,
#    'form_action' => nil,
#    'frame_ancestors' => nil,
#    'frame_src' => nil,
#    'img_src' => nil,
#    'manifest_src' => nil,
#    'media_src' => nil,
#    'object_src' => nil,
#    'script_src' => nil,
#    'style_src' => nil,
#    'worker_src' => nil,
#    'report_uri' => nil,
#  }
}

the uncommented part that enables CSP just sets Gitlab’s default policy. Please show exactly how and what you configured and ensure it was in /etc/gitlab/gitlab.rb and not any other files.

Also, after changing gitlab.rb you need to do:

gitlab-ctl reconfigure

to activate the changes. You may also wish to do:

gitlab-ctl restart
2 Likes

For git.coop which is running the CE version I updated /etc/gitlab/gitlab.rb to contain:

gitlab_rails['content_security_policy'] = {
 'enabled' => true,
 'report_only' => true,
}

And this resulted in the following HTTP header (additional new lines added to make it more readable):

curl -I https://git.coop/users/sign_in | grep ^content-security-policy-report-only | sed 's/;/;\n/g'
content-security-policy-report-only: base-uri 'self';
 child-src https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com https://www.googletagmanager.com/ns.html https://git.coop/admin/ https://git.coop/assets/ https://git.coop/-/speedscope/index.html https://git.coop/-/sandbox/ https://git.coop/assets/ blob: data:;
 connect-src 'self' wss://git.coop https://cdn.cookielaw.org https://*.onetrust.com *.google-analytics.com *.analytics.google.com *.googletagmanager.com;
 default-src 'self';
 font-src 'self';
 form-action 'self' https: http:;
 frame-ancestors 'self';
 frame-src https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com https://www.googletagmanager.com/ns.html https://git.coop/admin/ https://git.coop/assets/ https://git.coop/-/speedscope/index.html https://git.coop/-/sandbox/;
 img-src 'self' data: blob: http: https: *.google-analytics.com *.googletagmanager.com;
 manifest-src 'self';
 media-src 'self' data: blob: http: https:;
 object-src 'none';
 script-src 'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net https://apis.google.com https://cdn.cookielaw.org https://*.onetrust.com https://cdn.bizible.com/scripts/bizible.js *.googletagmanager.com 'nonce-i5jZKW5htTIUEA4ui0+Euw==';
 style-src 'self' 'unsafe-inline';
 worker-src https://git.coop/assets/ blob: data:

I then removed all the 3rd party URLs and generated this configuration:

gitlab_rails['content_security_policy'] = {
 'enabled' => true,
 'report_only' => true,
 'directives' => {
   'base_uri' => "'self'",
   'child_src' => "https://git.coop/admin/ https://git.coop/assets/ https://git.coop/-/speedscope/index.html https://git.coop/-/sandbox/ https://git.coop/assets/ blob: data:",
   'connect_src' => "'self' wss://git.coop",
   'default_src' => "'self'",
   'font_src' => "'self'",
   'form_action' => "'self' https: http:",
   'frame_ancestors' => "'self'",
   'frame_src' => "https://git.coop/admin/ https://git.coop/assets/ https://git.coop /-/speedscope/index.html https://git.coop/-/sandbox/",
   'img_src' => "'self' data: blob: http: https:",
   'manifest_src' => "'self'",
   'media_src' => "'self' data: blob: http: https:",
   'object_src' => "'none'",
   'script_src' => nil,
   'style_src' => "'self' 'unsafe-inline'",
   'worker_src' => "https://git.coop/assets/ blob: data:",
   'report_uri' => nil,
 }
}

Note that I have kept script_src as nill as it contains a nonce, is this approach sensible, or pointless as the headers still contains 3rd party URLs, is the configuration in /etc/gitlab/gitlab.rb just to add to the default policy rather than replace it?

If that is the case would I be better off with this configuration?

gitlab_rails['content_security_policy'] = {
 'enabled' => true,
}

The current headers:

curl -I https://git.coop/users/sign_in | grep ^content-security-policy-report-only | sed 's/;/;\n/g'
content-security-policy-report-only: base-uri 'self';
 child-src https://git.coop/admin/ https://git.coop/assets/ https://git.coop/-/speedscope/index.html https://git.coop/-/sandbox/ https://git.coop/assets/ blob: data:;
 connect-src 'self' wss://git.coop https://cdn.cookielaw.org https://*.onetrust.com *.google-analytics.com *.analytics.google.com *.googletagmanager.com;
 default-src 'self';
 font-src 'self';
 form-action 'self' https: http:;
 frame-ancestors 'self';
 frame-src https://git.coop/admin/ https://git.coop/assets/ https://git.coop /-/speedscope/index.html https://git.coop/-/sandbox/;
 img-src 'self' data: blob: http: https: *.google-analytics.com *.googletagmanager.com;
 manifest-src 'self';
 media-src 'self' data: blob: http: https:;
 object-src 'none';
 script-src 'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net https://apis.google.com https://cdn.cookielaw.org https://*.onetrust.com https://cdn.bizible.com/scripts/bizible.js *.googletagmanager.com 'nonce-5TdmOr6eM8mGu9XeUXjxMg==';
 style-src 'self' 'unsafe-inline';
 worker-src https://git.coop/assets/ blob: data:

Also does anyone have any suggestions regarding how to check that changing report_only to false won’t break anything?

Content security policy enabled now. But can we try using ‘nonce’ instead of ‘unsafe-inline’ in the existing configuration? I can’t find this to edit Does anyone know where it can be modified?