之前有一个问题(here https://stackoverflow.com/questions/11556131/parsing-a-json-like-string-that-contains-functions),但是那里的答案并没有准确回答我的问题 - 接受的答案包含无效的 JSON(强制使用eval()
),据我所知,根本不可能做这样的事情。
我计划使用我自己的服务器中的代码,该代码作为对象文字语法存储在字符串中,但是我也希望能够在其中存储函数。
目前,我想到了以下几种可能性:
- 只需使用
eval()
解析字符串
- 将函数以字符串形式放置(类似于
"\bfunction"
能够识别它们),运行JSON.parse()
然后使用 for-in 循环来查看是否需要解析任何此类函数(可能非常慢)
- 使用 DOM 来运行代码
<script>
标记并在那里运行它
该代码不会包含任何应该由用户编辑的内容,但是我不确定是否仍然存在安全问题或只是速度问题。会使用eval()
适合我的情况,有没有比手动解析函数或使用更有效的方法eval()
?
编辑:解析的替代语法会更好还是只会让事情变得更加复杂?
EDIT2:我只想做类似以下的事情:
{ "test": function () {}
, "foo": 1
, "bar": 2 }
I'm not想要从字符串中解析整个函数,例如
eval('function(){}');
效力(他们会做他们应该做的事吗?)
1、2 和 3 都可以工作
评估responseText:这会很好地工作。如果您根据安全建议 #3 添加同源质询,则必须首先更正它。
-
识别对象中要“复活”的单个项目。我以前使用过这种方法,并且更喜欢使用键的命名约定来确定何时恢复,而不是值中的标记。看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse有关复兴者的描述。
在情况 1 和 2 中,您必须以某种方式导致函数文本被解析和执行。这是您的选择。没有一个比其他的邪恶程度更小(请参阅安全部分)
如果您使用 f=eval(responseText),则这是“直接评估”。该函数将具有调用 eval 的本地范围。
如果您使用 f=(1,eval)(responseText),则这是“间接评估”。该函数将具有全局作用域。看http://perfectionkills.com/global-eval-what-are-the-options/ http://perfectionkills.com/global-eval-what-are-the-options/
如果使用 f=new Function(responseText),该函数将在全局作用域下具有单独的局部作用域。
此方法称为 JSONP(用于带填充的 JSON)。它会起作用,并且可能是最容易实现的。当响应可能包含敏感的用户数据时,这也不好(见下文)。
Security(他们会不会做不该做的事?)
如果传递的消息在您的控制之下(100% 确定没有用户/攻击者可以修改它):所有选项 1、2 和 3 都不会损害用户的浏览器状态(即 XSS,例如启用窃取其 cookie 等功能)。
如果传递的消息不是 100% 当然在您的控制之下:所有方法 1、2 和 3 都会损害用户的浏览器状态并且不安全。您的选择是:
接受安全风险(用户/攻击者将能够任意更改您的网站功能,包括但不限于:窃取您的用户的域 cookie、窃取用户在您的域上可以访问的任何信息、将您的用户引导至恶意软件- 受感染的页面可能会安装病毒)
将潜在不安全的函数传递给网络工作者并在那里运行它们。它们将被沙箱化并且不会影响浏览器窗口。然而,这需要更多的工作,并且并非在所有浏览器中都可用。
将潜在不安全的函数传递到单独域上的 iframe 中并在那里运行它们。这可以保护您用户的 cookie 等。但并不能阻止攻击者将他们重定向到利用站点来安装病毒(尽管您只能希望您的用户拥有安全的浏览器:-/)
使用您控制的白名单函数,并仅传递白名单函数的名称(或工厂函数,本质上是带有一些灵活参数的白名单函数)
如果您在数据中传递用户特定信息:
3 对于传递敏感用户数据来说并不安全(可以使用来自任何域的用户 cookie 轻松调用该脚本),除非您的服务器在返回响应之前对请求的引用/来源 HTTP 标头进行检查。即使这样,它也可能是不安全的。看http://en.wikipedia.org/wiki/Cross-site_request_forgery http://en.wikipedia.org/wiki/Cross-site_request_forgery
The naive选项 1、2 的实现以这种方式也是不安全的(即 XSRF。例如,恶意站点可以使用其 cookie 代表用户伪造数据请求,然后对其进行他们喜欢的操作)。第三方域可以重载内置的 Array 构造函数,然后插入指向 JSON 文件的脚本标记。浏览器会用用户的cookie请求这个文件,将用户的JSON返回给第三方站点,然后javascript引擎会“运行”这个JSON,这只是一条语句,但是因为Array构造函数已经被重载了,可以对数据执行任何操作,因为 javascript 会尝试在该单个 JSON“语句”中构造值
为了使 1 和 2 是 XSRF 安全的,您应该放置一条如果解释为脚本会导致其中断的语句,例如无效语法或无限循环,然后您的脚本应该接收文本并修改它以消除错误。这是因为同域脚本可以在解析请求之前读取请求的responseText,而跨域脚本只能通过插入以此为源的脚本标签来访问此信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)