Skip to content

Allow overriding Content Security Policy on published artefacts - #377

Open
mc1arke wants to merge 1 commit into
jenkinsci:masterfrom
mc1arke:content-security-policy
Open

Allow overriding Content Security Policy on published artefacts#377
mc1arke wants to merge 1 commit into
jenkinsci:masterfrom
mc1arke:content-security-policy

Conversation

@mc1arke

@mc1arke mc1arke commented Sep 15, 2025

Copy link
Copy Markdown
Member

Jenkins currently enforces a global Content Security Policy that prevents in-line styles and scripts from being loaded, so prevents archived HTML from tools that use such in-line elements from rendering properly. The workaround for this is to weaken the global policy by allowing such in-line elements to be loaded across Jenkins, although in some places people are recommending to disable CSP completely. To overcome this, the plugin is being altered to allow configuration to be set that enables scripts and styles, and dynamically injects these into the Content-Security-Policy header when serving archived artefacts.

JENKINS-75843, JENKINS-75769

Testing done

Automated test that shows sandbox attribute being altered on iframe, and Content-Security-Policy header being modified on serving of archived content. Manual testing shows a page that didn't render properly with current plugin now rendering properly with altered plugin:

Gatling report with default htmlpublisher configuration (scripts and styles fail to load):
image

image

Gatling report with altered htmlpublisher configuration (scripts and styles successfully load):
image

image

Similarly, ZAP report with default configuration (inline styles and images failing to load):

publishHTML([reportDir: 'zap-reports', reportFiles: 'zap_report.html', reportName: 'Zap Report', keepAll: true, allowMissing: true, alwaysLinkToLastBuild: true])
image image

Same report with styles and images enabled:

publishHTML([reportDir: 'zap-reports', reportFiles: 'zap_report.html', reportName: 'Zap Report', keepAll: true, allowMissing: true, alwaysLinkToLastBuild: true, contentSecurity: [styles: [allowUnsafeInline: true], images: [allowData: true]]])
image

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests that demonstrate the feature works or the issue is fixed

@mc1arke
mc1arke requested a review from a team as a code owner September 15, 2025 09:20
Comment thread src/main/java/htmlpublisher/ContentSecurity.java
@mc1arke
mc1arke force-pushed the content-security-policy branch from 65cab36 to a833257 Compare September 17, 2025 07:23
Jenkins currently enforces a global Content Security Policy that
prevents in-line styles and scripts from being loaded, so prevents
archived HTML from tools that use such in-line elements from rendering
properly. The workaround for this is to weaken the global policy by
allowing such in-line elements to be loaded across Jenkins, although in
some places people are recommending to disable CSP completely. To
overcome this, the plugin is being altered to allow configuration to be
set that enables scripts and styles, and dynamically injects these into
the Content-Security-Policy header when serving archived artefacts.

To ensure that a user with Job Configure permissions can't initially use
their access to enable a Content Security Policy to publish malicious
artefacts for attacking the Jenkins instance, the option to alter the
Content Security Policy is enabled instance-wide through a global
configuration by default, and must be enabled through the Jenkins UI by
an Administrator.
@mc1arke
mc1arke force-pushed the content-security-policy branch from a833257 to 08e6bea Compare September 17, 2025 08:10
@mvalvekensCET

mvalvekensCET commented Oct 14, 2025

Copy link
Copy Markdown

Hi, we have a similar issue. We use the resource root URL setting in Jenkins to serve artifacts from a different domain, which solves the issue for HTML files in the workflow artifact list. But reports published via this plugin don't seem to respect this setting.

Wouldn't it be better to make it so that the output of this plugin is served from behind the resource root, if configured? Then you don't need to mess with the CSP, and the risk of privilege escalation via session hijack by a user with job.Configure privileges also goes away. Or is that not something you can influence from within a plugin?

@sonarqubecloud

Copy link
Copy Markdown

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants