解析以字符串形式存储在对象常量/JSON语法中的函数,并进行区分 [英] Parsing functions stored as strings in object literal/JSON syntax and differetiating

查看:106
本文介绍了解析以字符串形式存储在对象常量/JSON语法中的函数,并进行区分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个先前的问题(此处),但是,那里的答案并不能完全回答我的问题-接受的答案包含无效的JSON(强制使用eval()),就我所知,这甚至是做不到的.

There is a previous question (here), however the answers there does not answer my question exactly - the accepted answer contained invalid JSON (mandating the use of eval()), which is simply not possible to do even something like that as far as I am aware.

我打算使用来自我自己的服务器的代码,该代码以对象文字语法形式存储在字符串中,但是我也希望能够在其中存储函数.

I'm planning to use code from my own server that is stored as object literal syntax in a string, however I'd like the ability to store functions in there as well.

当前,我想到了以下可能性:

Currently, I've thought of the following possibilities:

  1. 只需使用eval()即可解析字符串
  2. 以字符串形式放置函数(使用类似"\bfunction"的方法可以识别它们),在其上运行JSON.parse(),然后使用for-in循环查看是否需要解析任何此类函数(可能相当慢)
  3. 使用DOM通过<script>标记运行代码,然后在其中运行
  1. Simply use eval() to parse the string
  2. Place functions in string form (with something like "\bfunction" to be able to identify them), running JSON.parse() on it and then use a for-in loop to see whether any such functions need to be parsed (probably quite slow)
  3. Use the DOM to run the code using a <script> tag and just run it there

此代码将不包含任何应该由用户编辑的内容,但是我不确定是否仍然存在安全问题或只是速度问题.使用eval()是否适合我的情况?是否有比手动解析功能或使用eval()更有效的方法?

This code will not contain anything that's supposed to be user-editable, however I'm not sure whether there would still be a safety issue or just a speed one. Would using eval() be appropriate for my situation, and is there a more effective method of doing this than parsing for functions manually or using eval()?

解析语法的替代方法会更好还是会使事情变得更加复杂?

would an alternative syntax to parse be better or would that just make things even more complicated?

我只是想做以下事情:

I'm looking simply to do something like the following:

{ "test": function () {}
, "foo": 1
, "bar": 2 }

只是想从字符串中解析整个函数,例如

I'm not looking to just parse an entire function from a string, e.g.

eval('function(){}');

推荐答案

效果(他们会做应做的事情吗?)

Effectiveness (Will they do what they should do?)

1、2和3都可以使用

All of 1, 2, and 3 will work

  1. 评估responseText:可以正常工作.如果您根据安全建议3添加相同来源的挑战,则必须首先更正它.

  1. eval the responseText: This will work fine. If you add in a same-origin challenge per security recommendation #3, you must correct it first.

标识对象中的各个项目以恢复".我以前使用过这种方法,并且更喜欢对键使用命名约定来确定何时恢复,而不是在值中标记.请参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse ,以获取对遗忘者的描述.

Identify individual items in the object to "revive". I've used this approach before, and prefer to use a naming convention for the keys to determine when to revive, rather than a marker in the value. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse for a description of revivers.

在第1种情况和第2种情况下,您都必须以某种方式导致对函数文本进行解析和解析.被执行.这是您的选择.没有人比其他人真正邪恶(请参阅安全性部分)

In both cases 1 and 2, you will have to somehow cause the function text to be parsed & executed. Here are your options. None is really less evil than the others (see section on security)

如果使用f = eval(responseText),则这是直接评估".该函数将具有调用eval的本地范围.

If you use f=eval(responseText), this is a "direct eval". The function will have local scope where the eval is called.

如果您使用f =(1,eval)(responseText),则这是一个间接eval".该功能将具有全局范围.参见 http://perfectionkills.com/global-eval-what-are-the -options/

If you use f=(1,eval)(responseText), this is an "indirect eval". The function will have global scope. See http://perfectionkills.com/global-eval-what-are-the-options/

如果使用f = new Function(responseText),则该函数将在全局范围内具有单独的局部范围.

If you use f=new Function(responseText), the function will have a separate local scope under the global scope.

此方法称为JSONP(用于带填充的JSON).它会起作用,并且可能是最容易实现的.当响应中可能包含敏感的用户数据时,这也不是一件好事.(见下文).

This method is called JSONP (for JSON with padding). It will work and is probably the easiest to implement. It is also not good when the response may contain sensitive user data (see below).

安全性(他们会不做应该做的事吗?)

Security (Will they not do what they should not do?)

如果所传递的消息在您的控制之下(100%确保没有用户/攻击者可以对其进行修改): 选项1、2和3都不会损害用户的浏览器状态(即XSS,例如启用诸如窃取其Cookie的操作).

IF the delivered message IS under your control (100% sure no user/attacker can modify it): All of options 1, 2, and 3 do NOT compromise the user's browser state (i.e. XSS, e.g. enabling things like stealing their cookies).

如果所传递的消息不是100%当然在您的控制之下:方法1,方法2和方法3都会破坏用户的浏览器状态,并且是不安全的.您的选择是:

IF the delivered message IS NOT 100% certainly under your control: All of methods 1, 2, and 3 DO compromise the user's browser state and are unsafe. Your options are:

  • 接受安全风险(用户/攻击者将能够任意更改您的站点功能,包括但不限于:窃取您域的用户cookie,窃取用户在您的域中有权访问的任何信息,将您的用户定向到感染了恶意软件的页面,以潜在地安装病毒)

  • Accept the security risk (users/attackers will be able to arbitrarily change your site functionality, including but not limited to: stealing your users' cookies for the domain, stealing any information the user has access to on your domain, directing your users to malware-infested pages to potentially install viruses)

将可能不安全的功能传递给Webworker并在其中运行它们.它们将被沙盒化,并且不会影响浏览器窗口.但是,这需要更多工作,并且并非在所有浏览器中都可用.

Pass the potentially unsafe functions into a webworker and run them there. They will be sandboxed and cannot affect the browser window. However, this is more work and not available in all browsers.

将可能不安全的功能传递到单独域中的iframe中,然后在其中运行它们.这样可以保护您用户的Cookie等.但不能阻止攻击者将其重定向到利用站点来安装病毒(尽管您可以希望您的用户使用安全的浏览器:-/)

Pass the potentially unsafe functions into an iframe on a separate domain and run them there. This protects your users' cookies,etc. but does not prevent attackers from redirecting them to exploit sites to install viruses (though you can just hope your users have secure browsers :-/ )

使用您可以控制的列入白名单的函数,并仅传递该列入白名单的函数的名称(或实质上是具有一些灵活参数的列入白名单的函数的工厂函数)

Use whitelisted functions that you do control and just pass around the name of the whitelisted function (or factory functions that are essentially whitelisted functions with a few flexible parameters)

如果您在数据中传递了用户特定的信息:

  • 3不安全地传递敏感的用户数据(可以轻松地从任何域使用用户的cookie调用该脚本),除非您的服务器在返回请求的引用/原始HTTP标头之前执行检查回复.即使那样,它还是可以认为是不安全的.参见 http://en.wikipedia.org/wiki/Cross-site_request_forgery

选项1、2的天真实现也不安全(例如XSRF.例如,恶意网站可以使用Cookie代表用户伪造数据请求)然后用他们喜欢的方式做).第三方域可以重载内置Array构造函数,然后插入指向JSON文件的脚本标签.浏览器将使用用户的cookie来请求此文件,将用户的JSON返回到第三方站点,而javascript引擎将运行" JSON,这只是一条语句,但是由于Array构造函数已被重载,因此它javascript试图在单个JSON语句"中构造值时,可以对数据进行任何操作

The naive implementations of options 1, 2 are also unsafe in this way (i.e. XSRF. e.g. a malicious site can forge a request for the data on behalf of the user using their cookies and then do what they like with it). A third party domain can overload the built-in Array constructor and then insert a script tag pointing to the JSON file. The browser will request this file with the user's cookies, return the user's JSON to the third-party site, and the javascript engine will "run" the JSON, which is just a single statement, but because the Array constructor has been overloaded, it can do whatever it wants with the data as javascript tries to construct the value in that single JSON "statement"

为使1和2成为XSRF安全,您应该放置一条语句,如果将其解释为脚本(例如无效的语法或无限循环),则会导致其中断,那么您的脚本应接收文本并进行修改它可以消除错误.这是因为同域脚本可以在解析请求之前读取请求的responseText,而跨域脚本只能通过插入以此作为源的脚本标签来访问此信息.

For 1 and 2 to be XSRF safe, you should put a statement that would cause it to break if interpreted as a script, such as invalid syntax or an infinite loop, then your script should receive the text and modify it to remove the error. This is because same-domain scripts have access to read the responseText of a request before they parse it, whereas cross-domain scripts can only access this information by inserting a script tag with this as the source.

这篇关于解析以字符串形式存储在对象常量/JSON语法中的函数,并进行区分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆