Jenkins 错误 - <URL> 中的脚本执行被阻止。因为文档的框架是沙盒的,并且没有设置“允许脚本”权限

Posted

技术标签:

【中文标题】Jenkins 错误 - <URL> 中的脚本执行被阻止。因为文档的框架是沙盒的,并且没有设置“允许脚本”权限【英文标题】:Jenkins error - Blocked script execution in <URL>. because the document's frame is sandboxed and the 'allow-scripts' permission is not set 【发布时间】:2016-03-22 19:23:15 【问题描述】:

我知道,如果我们在 html 中使用 iFrame,我们必须对其进行沙箱处理并将“允许脚本”权限添加为 true。

但我的问题是我的纯 Angular JS 应用程序中根本没有 iFrame。当我在本地机器上运行它时,它工作正常。

当我将它部署到我的服务器时,Chrome 会显示此错误消息以及以下错误:

拒绝加载样式“bootstrap.min.css”,因为它违反了 遵循内容安全策略指令:“style-src 'self'”。

阻止脚本执行 'dashboard.html' 因为文档的框架是沙盒的,并且“允许脚本” 权限未设置。

我没有从第 3 方网站或其他地方调用可能会注入我的源并使其出现在 iframe 中的页面。我检查了代码,可以确认根本没有 iframe。

顺便说一句,我使用的是非常旧版本的 Chrome (26) 和 Firefox (10) [组织限制]。这也发生在 IE11 上(虽然没有显示错误消息)页面没有加载。

这可能是什么原因造成的?我在这里错过了什么吗?任何指针将不胜感激。

下面是我正在尝试做的事情的快照...修剪掉了琐碎的部分..

<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>

【问题讨论】:

【参考方案1】:

您需要按照以下步骤解决:

    打开 Jenkins 主页。 转到管理 Jenkins。 现在转到脚本控制台。 然后在该控制台中粘贴下面的语句并单击运行。 System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "") 之后它将加载 css 和 js。

注意:按照上述步骤后,如果仍然没有加载css和js,则清除浏览器缓存和cookie并刷新页面。

【讨论】:

(清除CSP属性后,)我需要重新运行测试,然后加载css和脚本。 这会完全覆盖(放松)安全实现,对吗?恢复到以前状态的命令应该是什么? @ronnyfm-重启你的Jenkins,它会恢复到之前的状态。【参考方案2】:

HTML Publisher Plugin 也有同样的问题。

根据Jenkins newContent Security Policy,可以通过设置绕过:

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

更新: 出于某种原因,在 Jenkins 2.x 上,我不得不再次使用空 CSP 值更新参数,而不是 script-src 'unsafe-inline,以便完全显示外部 HTML 页面:

-Dhudson.model.DirectoryBrowserSupport.CSP=

在 Windows 上,Jenkins 主目录中有一个 jenkins.xml,您可以在其中设置全局 JVM 选项,例如 Jenkins 系统属性。只需在参数标签下添加它:

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

对于大多数 Linux 发行版,您可以修改 JENKINS_ARGS 内部文件:

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

对于 CentOS,修改 JENKINS_JAVA_OPTIONS 里面的文件:

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

在内容安全策略参考中查看更多示例: http://content-security-policy.com/

【讨论】:

Global MAVEN_OPTS 用于将争论传递给 maven 而不是 Jenkins。所以它自然不会起作用。相反,您应该从 Jenkins 脚本控制台的 Manage Jenkins 链接下进行设置,然后在此处设置属性: System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "") @Venkat - 在 Jenkins 脚本控制台中运行 System.setProperty() 仅适用于当前 Jenkins 会话,因此您必须在下次 Jenkins 重新启动后再次运行它!而在 Jenkins Service Java 参数中设置它会使其成为全局。 是的,你是对的,而且确实必须这样做。 hi @Venkat 在从 firefox 设置此值后现在可以在 jenkins 中使用,但是对于 chrome 浏览器,它仍然显示此错误:因为它违反了以下内容安全策略指令:“script-src 'unsafe -排队'”。 ,有谁知道如何防止这个错误再次发生? @Nakilon - 你为什么编辑只是为了在参数中添加一个 标签?它破坏了 jenkins.xml。请解释或撤消。【参考方案3】:

对于托管在 Ubuntu 上的 Jenkins:

    发送至/etc/default/jenkins

    JAVA_ARGS="$JAVA_ARGS -Dhudson.model.DirectoryBrowserSupport.CSP=\"\" "
    

    访问http://&lt;your jenkins hostname&gt;/safeRestart

(关于此选项和其他选项:https://wiki.jenkins.io/display/JENKINS/Features+controlled+by+system+properties)

UPD:这次当我这样做时,访问 /safeRestart 是不够的。我必须做sudo service jenkins restart

【讨论】:

【参考方案4】:

以上答案在 Ubuntu 16.04 和 Jenkins 2.46.2 中对我不起作用。我不得不将 /etc/default/jenkins 中的 JAVA_ARGS 更改为

JAVA_ARGS="-Djava.awt.headless=true  -Dmail.smtp.starttls.enable=true -Dhudson.model.DirectoryBrowserSupport.CSP=\"sandbox allow-scripts; style-src 'unsafe-inline' *;script-src 'unsafe-inline' *;\""

更多信息here

【讨论】:

我还添加了“sandbox allow-same-origin”选项。【参考方案5】:

/etc/sysconfig/jenkins 底部的 Amazon Linux 上更改:

#JENKINS_ARGS="-Dhudson.model.DirectoryBrowserSupport.CSP=sandbox"

JENKINS_ARGS="-Dhudson.model.DirectoryBrowserSupport.CSP=\"\""

【讨论】:

【参考方案6】:

我们在 Jenkins userContent 目录中使用了这个 HTML 内容。我们最近升级到了最新的 Jenkins 1.625 LTS 版本,他们似乎引入了新的内容安全策略,将以下标头添加到响应标头中,浏览器只是拒绝执行样式表 / javascript 之类的任何内容。

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

为了克服它,我们必须通过在 Jenkins 中重置以下属性来简单地删除此标头。

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

升级到 Jenkins 1.625 并使用 userContent 文件夹的用户可能会受到此更改的影响。

更多信息请参考https://wiki.jenkins-ci.org/display/JENKINS/Configuring+Content+Security+Policy

【讨论】:

嗨 @Venkat 在从 firefox 设置此值后现在可以在 jenkins 中使用,但是对于 chrome 浏览器,它仍然显示此错误:因为它违反了以下内容安全策略指令:“script-src 'unsafe -排队'”。 ,有谁知道如何防止这个错误再次发生? @AlterHu - 你确定 script-src: unsafe-inline 来自 Jenkins 吗?根据文档,不会添加这些标题。默认规则设置为:沙盒;默认源代码“无”; img-src '自我'; style-src 'self'; 它不是来自 jenkins 官方网站,而是来自 sooneone 的回答,就像下面来自 Nakilon 的 cmets 一样。我发现引起的根源是chrome浏览器需要重新启动并完全清除会话,然后您可以在jenkins中显示html页面,您的回答很好。 感谢您的确认 :) 很高兴我的回答对您有所帮助。

以上是关于Jenkins 错误 - <URL> 中的脚本执行被阻止。因为文档的框架是沙盒的,并且没有设置“允许脚本”权限的主要内容,如果未能解决你的问题,请参考以下文章

通过URL触发Jenkins构建

设置 Github Jenkins 插件时出现“无法连接到存储库”错误

解决Jenkins maven SNAPSHOT相关jar无法拉取问题

基于tomcat安装jenkins遇到的问题

与 Jenkins 的错误集成 Allure 报告。找不到 allure 命令行 <null>

Jenkins(持续集成)Windows版本解决插件安装缓慢