Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins error - Blocked script execution in <URL>. because the document's frame is sandboxed and the 'allow-scripts' permission is not set

I'm aware that if we use a iFrame in HTML we've to sandbox it & add the 'allow-scripts' permission to be true.

But my problem is I don't have a iFrame at all in my pure Angular JS application. When I run it on my local machine it works fine.

The moment I deploy it to my server, Chrome displays this error message along with the below error:

Refused to load the style 'bootstrap.min.css' because it violates the following Content Security Policy directive: "style-src 'self'".

Blocked script execution in 'dashboard.html' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.

I'm not invoking the page from a 3rd party site or elsewhere which could possibly inject my source & make it appear in a iframe. I inspected the code & I can confirm there are no iframes at all.

BTW, I use a very old version of Chrome (26) and Firefox (10) [Organisational restrictions]. This happens on IE11 as well (Though no error message displayed) the page doesn't load up.

What could be causing this ? Am I missing anything here ? Any pointers would be greatly appreciated.

Below is a snapshot of what I'm trying to do... Trivial parts trimmed out..

<html lang="en" ng-app="dashboard">
   <head>
      <title>Dashboard</title>
      <link href="css/bootstrap.min.css" rel="stylesheet">
      <script src="js/jquery.min.js"></script>
      <script src="js/angular.min.js"></script>
      <script src="js/ui-bootstrap-tpls-0.6.0.js"></script>
      <script src="js/bootstrap.min.js"></script>
      <script src="js/notifications.js"></script>
      <style>
         body { background-color: #F3F3F4; color: #676a6c; font-size: 13px;}
      </style>
      <script>
         var dashboardApp = angular.module('dashboard', ['ui.bootstrap', 'notificationHelper']);
         
         Type = {
            APP : 0, CTL : 1
         }
         
         
         function DashboardCtrl($scope, $location, $timeout, $http, $log, $q) {
            $scope.environments = [ { ... }];
            $scope.columns = [ { ... } ];
         
             $scope.Type = window.Type;
            $scope.applications = [{ ... }];
         
            $scope.selectedEnv = null;
         
            var resetModel = function(applications) {
                applications.forEach(function(app) {
                     var hosts=$scope.findHosts(app, $scope.selectedEnv);
                     if(hosts){
                         hosts.forEach(function(host){
                             $scope.initStatus(app.status,host);
                         });
                     }
                });
            };
         
            var timeoutPromise = null;
         
             $scope.initStatus = function (status,host) {
                 status[host]=[{
                     ...
                 }];
         
             };             
         }
         
      </script>
   </head>
   <body ng-controller="DashboardCtrl">
      <div class="request-notifications" ng-notifications></div>
      <div>
         <tabset>
            <tab ng-repeat="env in environments" heading="{{env.name}}" select="set(env)" active="env.tab_active">
               <div class="col-md-6" ng-repeat="column in columns" ng-class="{'vertical-seperator':$first}">
                  <div class="panel" ng-class="{'first-child':$first}">
                     <div class="panel-heading">
                        <h3>{{column.column}}</h3>
                     </div>
                     <div class="panel-body">
                        <div class="frontends" ng-repeat="layer in column.layers">
                           <h4>{{layer.name}}</h4>
                           <div class="category" ng-repeat="category in layer.categories" ng-class="category.css">
                              <div class="category-heading">
                                 <h4>{{category.name}}</h4>
                              </div>
                              <div class="category-body group" ng-repeat="group in category.groups">
                                 <div ng-if="!env[group.host]">
                                    <h4>{{group.name}}</h4>
                                    <span class="label label-danger">Not deployed</span>
                                 </div>
                                 <div ng-repeat="host in env[group.host]">
                                    <div class="group-info">
                                       <div class="group-name">{{group.name}}</div>
                                       <div class="group-node"><strong>Node : </strong>{{host}}</div>
                                    </div>
                                    <table class="table table-striped">
                                       <thead>
                                          <tr>
                                             ...
                                          </tr>
                                       </thead>
                                       <tbody>
                                          <tr class="testStatusPage" ng-repeat="app in apps | filter: { column: column.column, layer: layer.name, category: category.name, group: group.name } : true">
                                             <!-- Application Home Links -->
                                             <td class="user-link" ng-if="app.type === Type.A || app.type === Type.A1 || app.type === Type.B || app.type === Type.B1 || app.type === Type.C"><a href="{{app.link}}">{{app.text}}</a></td>                                                                                          <td ng-if="app.status[host].statusCode == 0" class="result statusResult"><span class="label label-success">Success</span></td>
                                             <td ng-if="app.status[svr].status != null && app.status[host].status != 0" class="result statusResult"><span class="label label-danger">{{app.status[host].error}}</span></td>
                                          </tr>
                                       </tbody>
                                    </table>
                                 </div>
                              </div>
                           </div>
                        </div>
                     </div>
                  </div>
               </div>
            </tab>
         </tabset>
      </div>
   </body>
</html>
like image 734
Venkat Avatar asked Dec 16 '15 15:12

Venkat


4 Answers

We were using this content HTML in a Jenkins userContent directory. We recently upgraded to the latest Jenkins 1.625 LTS version & it seems they've introduced new Content security policy which adds the below header to the response headers & the browsers simply decline to execute anything like stylesheets / Javascripts.

X-Content-Security-Policy: sandbox; default-src 'none'; img-src 'self'; style-src 'self';

To get over it, we had to simply remove this header by resetting the below property in Jenkins.

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")

Those who upgrade to Jenkins 1.625 & use the userContent folder might be affected by this change.

For more information refer https://wiki.jenkins-ci.org/display/JENKINS/Configuring+Content+Security+Policy

like image 185
Venkat Avatar answered Nov 11 '22 17:11

Venkat


You need to follow below steps for solution :

  1. Open the Jenkin home page.
  2. Go to Manage Jenkins.
  3. Now go to Script Console.
  4. And in that console paste below statement and click on Run. System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")
  5. After that it will load css and js.

Note : After following the above steps if still it is not loading css and js then clear the browser cache and cookie and refresh the page.

like image 44
Ronak Avatar answered Nov 11 '22 15:11

Ronak


I had the same issue with HTML Publisher Plugin.

According to Jenkins new Content Security Policy, you can bypass it by setting:

hudson.model.DirectoryBrowserSupport.CSP=script-src 'unsafe-inline';

UPDATE: For some reason on Jenkins 2.x, I had to update arguments again, with an empty CSP value, instead of script-src 'unsafe-inline, in order to fully display external HTML pages:

-Dhudson.model.DirectoryBrowserSupport.CSP=

On Windows there's a jenkins.xml in Jenkins home directory, where you can set global JVM options, such as Jenkins system properties. Simply add it under arguments tag:

<arguments> -Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle "-Dhudson.model.DirectoryBrowserSupport.CSP= " -jar "%BASE%\jenkins.war" --httpPort=8080 </arguments>

For most of the Linux distributions, you can modify JENKINS_ARGS inside file:

/etc/default/jenkins (or jenkins-oc)

For CentOS, modify JENKINS_JAVA_OPTIONS inside file:

/etc/sysconfig/jenkins (or jenkins-oc)

See more examples in the Content Security Policy Reference: http://content-security-policy.com/

like image 29
Noam Manos Avatar answered Nov 11 '22 16:11

Noam Manos


For Jenkins hosted on Ubuntu:

  1. put to /etc/default/jenkins

    JAVA_ARGS="${JAVA_ARGS} -Dhudson.model.DirectoryBrowserSupport.CSP=\"\" "
    
  2. visit http://<your jenkins hostname>/safeRestart

(about this and other options: https://wiki.jenkins.io/display/JENKINS/Features+controlled+by+system+properties)

UPD: this time when I did this the visiting /safeRestart was not enough. I had to do sudo service jenkins restart.

like image 9
Nakilon Avatar answered Nov 11 '22 15:11

Nakilon