chrome 包应用程序中的 eval

Posted

技术标签:

【中文标题】chrome 包应用程序中的 eval【英文标题】:eval in chrome package app 【发布时间】:2012-08-07 11:41:19 【问题描述】:

我想创建一个包应用程序 chrome 扩展,以允许用户编写和执行 javascript 代码(如 javascript 控制台)。

我想使用eval()函数来执行JS代码。

经典的 javascript eval 函数在从 chrome 扩展程序调用时会引发错误:

未捕获的错误:此上下文不允许从字符串生成代码

要在 chrome 扩展程序中使用 eval,人们需要使用 sandbox,但是当我在清单中编写沙箱时,我会收到以下错误:

尝试安装此扩展程序时出现警告: 指定的包类型(主题、应用等)不允许使用“沙盒”。

更新

根据this issue的说法,打包应用不支持沙箱,所以我有两个问题:

    我可以用其他方法代替eval()吗?

    是否可以在没有沙箱的情况下使用eval? (我想可能不是出于安全原因?)

【问题讨论】:

我对此了解不多,但使用js.js 可能是一种可能的(尽管性能较差)解决方案。 【参考方案1】:

这是一个不起作用的示例,因为所有带有代码的字符串都将在 Chrome 打包应用程序中被拒绝:

//To run some code from a string without `eval` just do this:
var code = new Function(yourCodeString);
code();

【讨论】:

谢谢,但同样的问题:未捕获的错误:此上下文不允许从字符串生成代码 不知道...您可能是对的,也许这是一个安全问题,他们禁用了它。 内容安全政策禁止在 Chrome 扩展程序中生成任何类型的动态代码 - 无论是 eval() 还是 new Function() 这里是有关此文档的链接,其中显示的示例表明不支持 JavaScript 的任何字符串评估。 developer.chrome.com/extensions/contentSecurityPolicy.html。考虑在您的帖子中添加edit 以纠正不准确之处,或考虑将其删除。祝你好运! :) 好的,所以我认为你的帖子是一个很好的例子,说明什么是起作用的,而且这里的事实确实澄清了一些关于谷歌到底有多远的观点愿意去保护我们的安全;),所以我编辑了您的帖子以使其正确并且对未来的访问者仍然有用,保留您答案的核心。希望这可以帮助! +1【参考方案2】:

更新:

至少从 2013 年 1 月开始,Chrome 现在允许 unsafe-eval 内容安全策略 (CSP) 指令,该指令允许在沙盒之外执行 eval

可以通过在您的政策中添加 'unsafe-eval' 来放宽针对 eval() 及其亲属(如 setTimeout(String)setInterval(String)new Function(String))的政策

为您的扩展清单添加适当的CSP,例如:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"

bug you refer to 现在标记为 fixed,并且自 Chrome 22 起已包含在内。

在引入'unsafe-eval' 之前,没有办法让manifest_version: 2 扩展的CSP 允许将任意文本作为代码执行。 At the time,Google 明确表示无法移除此限制(沙盒之外):

内联 JavaScript 以及危险的字符串到 JavaScript 方法(如 eval)将不会被执行......没有机制可以放宽对执行内联 JavaScript 的限制。特别是,设置包含unsafe-inline 的脚本策略将不起作用。这是故意的。

如上所述,这个限制现在可以放宽了。

【讨论】:

您可以更新您的答案以提及unsafe-eval 指令developer.chrome.com/extensions/… 确保在 manifest.json 中添加后重新加载扩展。 我只想补充一点,此方法仅适用于扩展程序,不适用于packaged apps(因为线程的标题是指打包的应用程序)。 @PatriciaGarcia 有趣,是的——这里的混淆似乎是“打包应用程序”一词指的是两个非常不同的东西,而 OP 的链接错误报告指的是“遗留打包应用程序”,基本上 带有应用程序屏幕图标的扩展程序。但是,OP 很可能没有意识到关于错误报告的这一点(我也没有),实际上意味着现代打包的应用程序。感谢您指出了这一点;我会看看能否尽快澄清这个答案。【参考方案3】:

你可以试试……

function evalMe(code)
    var script = document.createElement('script');
    script.innerText = code;
    document.querySelector('head').appendChild(script);

这应该会产生相同的效果,除非他们也禁用了它,但据我所知,这很好。当然,如果脚本 errors 你不会听到它,除非你将 string 包装成 eval 例如

function myHandler(err)
    // handle errors.   


function evalMe(code)
    var script = document.createElement('script');
    var wrapper = '(function() try @@ catch(err) myHandler(err);  )()';
    // Make sure the string has an ending semicolon
    code = code[code.length-1] === ';' ? code : code + ';';

    script.innerText = wrapper.replace('@@', code);
    document.querySelector('head').appendChild(script);

或者你可以使用官方机制

http://developer.chrome.com/beta/extensions/tabs.html#method-executeScript

但是,这需要您有一个background page 并在您的app 页面和背景页面之间使用message passing。

更新:工作方法

您可以使用 iframe 和 base64 编码的 dataURI 创建类似 eval 的方法,以处理扩展页面和 <iframe> 之间的消息传递。您可以获取code on github 的工作副本。要使用简单的克隆或下载 repo,并在 chrome 扩展管理器中安装“客户端”dir 作为未打包的扩展。驱动插件的代码位于app.js

使用 iframeEval 进行测试,错误通知有点错误,但是,eval 有效。

@appsillers 为了让你的插件在没有任何额外代码的情况下工作,你可以用代码中的iframeEval 方法覆盖你的扩展window 上的eval 方法。

【讨论】:

manifest_version: 2 不允许内联脚本,所以我预计 evalMe 会产生错误,因为它会使用内联脚本注入 <script>。您关于传递消息以在后台执行executeScript 的最终建议是一个有趣的可能性,但我认为它可能会受限于单独的执行环境,就像后台页面一样。我会测试一下是否正确。 我刚刚测试了我的第一点,evalMe 产生了错误Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:". 嗯,让我在文档中进行更多挖掘。作为一个问题,评估的脚本是否需要访问页面DOM?或者他们是pure.js 我假设不是,否则eval 将非常危险,因为您授予eval'ed 代码访问 chrome API 的权限。除非这是你的意图【参考方案4】:

我想您是在谈论新的打包应用程序(清单版本 2),对吧?

沙盒绝对可以在新打包的应用程序中使用。上周我刚刚上传了a sample,它确实做到了:一个窗口向隐藏的沙盒 iframe 发送消息,iframe 编译一个把手模板(这里它可以使用 eval 代替)并将编译后的 HTML 返回到托管页面,它显示结果。

您也可以查看this other sample,这正是您想要的。

所以,直接回答你的问题:

1) 否,因为 CSP 限制。在 Chrome 打包应用程序中评估动态 JavaScript 的唯一方法是沙盒 iframe。如果这不是您的应用程序的选项,您还可以在服务器中发送和评估 JavaScript 内容,然后只将结果返回给用户(尽管这会破坏 Chrome 打包应用程序的离线功能)

2) 不可以,您只能在沙盒 iframe 中使用 eval()。

【讨论】:

两个链接都坏了 已修复。 Github 仓库已重构,导致 URL 无效。【参考方案5】:

在我开始的 Angular.js chrome 应用程序给出了同样的错误之后,我得到了这个答案。作者没有提到 Angular.js,但如果其他人遇到这个,你需要在你的网页上添加一个额外的指令,例如

<html ng-app ng-csp>
...

这会将 Angular 置于 CSP 安全模式 https://docs.angularjs.org/api/ng/directive/ngCsp

【讨论】:

【参考方案6】:

你可以使用:$scope.$eval() from angular。

【讨论】:

欢迎来到 ***。您可能应该在某种程度上详细说明您的问题:您是否对此进行了测试,或者您是否有一些经验,或者只是提出了一个您想到的想法?虽然后者也可能没问题,但更详细的答案更受欢迎。另外,请使用代码包装器。最好的问候。

以上是关于chrome 包应用程序中的 eval的主要内容,如果未能解决你的问题,请参考以下文章

这是 Chrome 错误还是我使用“use strict”和 eval 无效?

Angular 2,iOS Safari 错误:eval@[native code]

Python面向对象:异常模块和包文件eval函数

Python面向对象:异常模块和包文件eval函数

嵌入式 Cordova 应用程序包正在 Chrome 中打开,而不是在我的 Android 应用程序中启动

js中的eval方法详解–eval方法中的高级应用