Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-61925

Upcoming Chrome SameSite policy change will break HTML Publisher plugin

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • htmlpublisher-plugin
    • None
    • Jenkins 2.228
      htmlpublisher v1.22

      Google Chrome is about to change behavior for cookies without a SameSite attribute, see https://web.dev/samesite-cookies-explained/ and https://www.chromium.org/updates/same-site. The rollout, originally planned for February/March, has now been postponed until the summer. Other browsers will eventually ship the same changes.

      We're using the HTML Publisher plugin to publish LCOV-generated code coverage reports. The new SameSite behavior described above, together with the default Content-Security-Policy header, seems to break this use case. Specifically, the cookies set by Jenkins don't include a SameSite attribute and therefore are no longer being sent by the browser when the HTML report page tries to load additional resources (CSS and images), because they are considered cross-site requests. And without the session cookie, these requests are rejected by Jenkins with an HTTP 403 error.

      Removing "sandbox" from the default hudson.model.DirectoryBrowserSupport.CSP setting works around the issue, but seems less than ideal.

          [JENKINS-61925] Upcoming Chrome SameSite policy change will break HTML Publisher plugin

          Andras Kovi added a comment -

          Hi r2b2_nz, the problem is probably not the HTML Publisher but the way Jenkins produces the cookies. The plugin just serves the files, I guess. But if there are CORS requests from the browser, and the cookie would need to be sent back to Jenkins, then Chrome will refuse to do that. This can happen with any kind of CORS requests: css, script, xhr... It kind of depends on the Jenkins settings, of course, as the fault can only be activated if CORS requests are allowed by the server settings.

          In general, as the cookie is produced by Jenkins, this should be moved to be a Jenkins core issue. But as such, it should be high priority as gradually this will cause more problems as new Chrome versions roll out. Currently, in cases where "smart" HTML reports are used, this can cause complete shutdown of some functionalities.

          Andras Kovi added a comment - Hi r2b2_nz , the problem is probably not the HTML Publisher but the way Jenkins produces the cookies. The plugin just serves the files, I guess. But if there are CORS requests from the browser, and the cookie would need to be sent back to Jenkins, then Chrome will refuse to do that. This can happen with any kind of CORS requests: css, script, xhr... It kind of depends on the Jenkins settings, of course, as the fault can only be activated if CORS requests are allowed by the server settings. In general, as the cookie is produced by Jenkins, this should be moved to be a Jenkins core issue. But as such, it should be high priority as gradually this will cause more problems as new Chrome versions roll out. Currently, in cases where "smart" HTML reports are used, this can cause complete shutdown of some functionalities.

          Thanks akovi. I'm trying to get my head around it (my head is currently also in another space so trying to bounce between the two ) so slowly getting there.

          It seems to me that the issue isn't actually with Jenkins itself but with the cookies being served from third-party sites that are linked to from the HTML that is being published via Jenkins. Does that seem an accurate assessment? It would be useful if someone can confirm that (you can see which cookies are being blocked in the Developer Tools "Issues" tab)

          If that's the case then there still is the issue that even if it sends through a "Lax" setting it still probably won't send the cookie as only "None" will work when in an iframe but if I can at least determine that I'm on the right track then I know where to focus my efforts.

          Richard Bywater added a comment - Thanks akovi . I'm trying to get my head around it (my head is currently also in another space so trying to bounce between the two ) so slowly getting there. It seems to me that the issue isn't actually with Jenkins itself but with the cookies being served from third-party sites that are linked to from the HTML that is being published via Jenkins. Does that seem an accurate assessment? It would be useful if someone can confirm that (you can see which cookies are being blocked in the Developer Tools "Issues" tab) If that's the case then there still is the issue that even if it sends through a "Lax" setting it still probably won't send the cookie as only "None" will work when in an iframe but if I can at least determine that I'm on the right track then I know where to focus my efforts.

          Andras Kovi added a comment -

          r2b2_nz the HTML running in the iframe starting requests toward Jenkins are the problematic ones as these requests do include the cookie. External sites and their cookies are not in play here. Jenkins must produce a cookie that conforms to the new rules. For example, an HTML containing a reference to a CSS, like so:

          <head>
              <link rel="stylesheet" href="css/materialize.min.css">
          <head>
          Text

          The request for the css will fail with the message mentioned earlier. The cookie is mandatory as it contains the authentication info. Here is a screenshot:

          Andras Kovi added a comment - r2b2_nz the HTML running in the iframe starting requests toward Jenkins are the problematic ones as these requests do include the cookie. External sites and their cookies are not in play here. Jenkins must produce a cookie that conforms to the new rules. For example, an HTML containing a reference to a CSS, like so: <head> <link rel= "stylesheet" href= "css/materialize.min.css" > <head> Text The request for the css will fail with the message mentioned earlier. The cookie is mandatory as it contains the authentication info. Here is a screenshot:

          Facundo Mateo added a comment - - edited

          r2b2_nz All jenkins cookies are being blocked  (JSESSIONID and the screen size one)

          My environment is  Jenkins 2.235.3 runing behind apache proxy.  We are using pipelines to build a java project  and publish coverage report, which is provided by Clover plugin. 

          This report is served by jenkins as an external resource. At first we were affected by Security Policy issues.  As stated in https://wiki.jenkins.io/display/JENKINS/Configuring+Content+Security+Policy we need to configure a resource root to go around this.  Meanwhile, we got all working  relaxing  security measures until domain configuration is done. 

          After chrome update, the initial report  page is rendered but related resources cannot because SameSite cookie policy. 

           

          GET https://xxxxxxxxx/clover/.css/bootstrap.min.css net::ERR_ABORTED 403
          dashboard.html:8 GET https://xxxxxxxxx/clover/.css/nv.d3.min.css net::ERR_ABORTED 403
          dashboard.html:9 GET https://xxxxxxxxx/clover/.css/style.css net::ERR_ABORTED 403
          dashboard.html:10 GET https://xxxxxxxxx/clover/.css/custom.css net::ERR_ABORTED 403
          dashboard.html:294 GET https://xxxxxxxxx/clover/.js/jquery.min.js net::ERR_ABORTED 403
          dashboard.html:295 GET https://xxxxxxxxx/clover/.js/d3.min.js net::ERR_ABORTED 403
          dashboard.html:296 GET https://xxxxxxxxx/clover/.js/nv.d3.min.js net::ERR_ABORTED 403
          dashboard.html:298 Uncaught ReferenceError: $ is not defined
          

           

          Facundo Mateo added a comment - - edited r2b2_nz All jenkins cookies are being blocked  (JSESSIONID and the screen size one) My environment is  Jenkins 2.235.3 runing behind apache proxy.  We are using pipelines to build a java project  and publish coverage report, which is provided by Clover plugin.  This report is served by jenkins as an external resource. At first we were affected by Security Policy issues.  As stated in https://wiki.jenkins.io/display/JENKINS/Configuring+Content+Security+Policy  we need to configure a resource root to go around this.  Meanwhile, we got all working  relaxing  security measures until domain configuration is done.  After chrome update, the initial report  page is rendered but related resources cannot because SameSite cookie policy.    GET https: //xxxxxxxxx/clover/.css/bootstrap.min.css net::ERR_ABORTED 403 dashboard.html:8 GET https: //xxxxxxxxx/clover/.css/nv.d3.min.css net::ERR_ABORTED 403 dashboard.html:9 GET https: //xxxxxxxxx/clover/.css/style.css net::ERR_ABORTED 403 dashboard.html:10 GET https: //xxxxxxxxx/clover/.css/custom.css net::ERR_ABORTED 403 dashboard.html:294 GET https: //xxxxxxxxx/clover/.js/jquery.min.js net::ERR_ABORTED 403 dashboard.html:295 GET https: //xxxxxxxxx/clover/.js/d3.min.js net::ERR_ABORTED 403 dashboard.html:296 GET https: //xxxxxxxxx/clover/.js/nv.d3.min.js net::ERR_ABORTED 403 dashboard.html:298 Uncaught ReferenceError: $ is not defined  

          Hi everyone - thanks for all the info. I think I have now got my head around the issue although I might not be 100% correct in what I'm about to say so please correct me if you see errors or omissions

          The issue appears to be happening as the iframe is being sandboxed by default with the Content Security Policy and with the Chrome (and other browsers at some stage presumably) changes this mean that the cookie isn't being sent as it is treating the iframe content is third-party.

          I believe the only way to fix it to work without making any other config changes would be to have Jenkins set SameSite to None for the (e.g.) JSESSIONID cookie which wouldn't be a very good idea from a security point of view and also coupled with that you also need to make that cookie Secure which would then break any non-HTTPS Jenkins instances.

          I've tested three different ways that appear to fix the issue for my (very) simple use-case and so these may or may not work with the more complicated content involved. The three ways are:

          1. Change the Content Security Policy to not have 'sandbox'
          2. Change the Content Security Policy to have 'sandbox' but change to 'sandbox allow-same-origin'
          3. Make use of the Resource Root URL functionality available in Jenkins 2.200+

          The first two do have security implications so I'd say that, wherever possible, use of the Resource Root URL would probably be the best option but, please note as above, I haven't tested that at the moment with more complicated reports than a simple bit of CSS and simple bit of JS.

          Keen to hear any feedback - I will keep looking to make sure there's nothing I've missed / can easily change but at the moment this seems to be the main way of "fixing" the issue.

          Richard Bywater added a comment - Hi everyone - thanks for all the info. I think I have now got my head around the issue although I might not be 100% correct in what I'm about to say so please correct me if you see errors or omissions The issue appears to be happening as the iframe is being sandboxed by default with the Content Security Policy and with the Chrome (and other browsers at some stage presumably) changes this mean that the cookie isn't being sent as it is treating the iframe content is third-party. I believe the only way to fix it to work without making any other config changes would be to have Jenkins set SameSite to None for the (e.g.) JSESSIONID cookie which wouldn't be a very good idea from a security point of view and also coupled with that you also need to make that cookie Secure which would then break any non-HTTPS Jenkins instances. I've tested three different ways that appear to fix the issue for my (very) simple use-case and so these may or may not work with the more complicated content involved. The three ways are: Change the Content Security Policy to not have 'sandbox' Change the Content Security Policy to have 'sandbox' but change to 'sandbox allow-same-origin' Make use of the Resource Root URL functionality available in Jenkins 2.200+ The first two do have security implications so I'd say that, wherever possible, use of the Resource Root URL would probably be the best option but, please note as above, I haven't tested that at the moment with more complicated reports than a simple bit of CSS and simple bit of JS. Keen to hear any feedback - I will keep looking to make sure there's nothing I've missed / can easily change but at the moment this seems to be the main way of "fixing" the issue.

          Andras Kovi added a comment -

          Excellent, thank you Richard!

          I will make sure to try option 2. The Resource Root URL was in use for a little while but some plugins were not compatible so it was reverted.

          I'll get back to you as soon as possible.

          Andras Kovi added a comment - Excellent, thank you Richard! I will make sure to try option 2. The Resource Root URL was in use for a little while but some plugins were not compatible so it was reverted. I'll get back to you as soon as possible.

          Facundo Mateo added a comment -

          Thanks for the information Richard.

          I will test option 3 today .  We have all the configuration ready for the Resource Root URL alternative.

          Currently my testing environment is working with a sandboxed and relaxed  Content security Policy. Is straightfoward  to test option 2 either.

          I will let you know the results.

          Facundo Mateo added a comment - Thanks for the information Richard. I will test option 3 today .  We have all the configuration ready for the Resource Root URL alternative. Currently my testing environment is working with a sandboxed and relaxed  Content security Policy. Is straightfoward  to test option 2 either. I will let you know the results.

          Facundo Mateo added a comment -

          Both solutions (option 2 and 3) works as expected. 

          We will stay with Resource Root Url as it seems more secure  solution.

          Facundo Mateo added a comment - Both solutions (option 2 and 3) works as expected.  We will stay with Resource Root Url as it seems more secure  solution.

          Poomrat Boonyawong added a comment - - edited

          Stumbled upon this bug in my environment and happy to report solution #2 works. I had looked at resource root earlier but it seems pretty complex to set up properly.

          Hope to have the build with proper SameSite to test so I can remove this hack.

          Poomrat Boonyawong added a comment - - edited Stumbled upon this bug in my environment and happy to report solution #2 works. I had looked at resource root earlier but it seems pretty complex to set up properly. Hope to have the build with proper SameSite to test so I can remove this hack.

          Jean-Luc Pé added a comment -

          Hello !

          In the jenkins instance I manage, a developer has created an HTML page that has a Download button. This html page is published with HTML Publisher.
          It works as awaited with Firefox. But not with Chrome for the same reason invoked in this issue.
          I tried to configure the Resource Root URL, but it cannot be configured with the same URL as JENKINS URL.
          Is there a secure way to mak this work ?

          Jean-Luc Pé added a comment - Hello ! In the jenkins instance I manage, a developer has created an HTML page that has a Download button. This html page is published with HTML Publisher. It works as awaited with Firefox. But not with Chrome for the same reason invoked in this issue. I tried to configure the Resource Root URL, but it cannot be configured with the same URL as JENKINS URL. Is there a secure way to mak this work ?

            r2b2_nz Richard Bywater
            pesa Davide Pesavento
            Votes:
            8 Vote for this issue
            Watchers:
            10 Start watching this issue

              Created:
              Updated: