简体   繁体   English

如何避免在用户定义的函数中使用JavaScript eval()

[英]How to avoid using JavaScript eval() in user-defined function

I'm trying to make a generic table-top RPG helper web app. 我正在尝试制作一个通用的桌面RPG助手Web应用程序。 It has to be generic because Wizards of the Coast is very protective of their copyrights. 它必须是通用的,因为“海岸奇才”非常保护其版权。 So, in order to avoid cease-and-desists, the system has to be capable of loading arbitrary rules. 因此,为了避免停下来,该系统必须能够加载任意规则。 That said, my buddies and I (along with most any other user) will be using it for D&D. 就是说,我和我的好友(以及大多数其他用户)将使用它进行D&D。

In D&D, modifiers are based on a character's stats. 在D&D中,修饰符基于角色的属性。 To get a modifier, you take the stat, subtract 10, divide by 2, and round down. 要获取修饰符,您需要获取统计信息,然后减去10,除以2,然后四舍五入。

function getModifier(statValue) {
    return Math.floor((statValue - 10) / 2);
}

My app will be capable to loading a game's rules from a .json file. 我的应用程序将能够从.json文件加载游戏规则。 I want to be able to make this modifier function user-definable. 我希望能够使此修饰符功能可由用户定义。 The easiest way would be to just eval() whatever they provide in the .json file, but obviously that's a terrible idea due to security issues. 最简单的方法是仅对.json文件中提供的内容进行eval() ,但是由于安全问题,显然这是一个糟糕的主意。

Unfortunately, I can't think of a simple way to get around this in a secure manner. 不幸的是,我想不出一种简单的方法来以安全的方式解决这个问题。 Obviously I could write my own parser, but that's more complicated than I'd like/am currently capable of. 显然,我可以编写自己的解析器,但这要比我目前想要的更加复杂。

Ideas? 有想法吗?

First, bear in mind that this is all on the client-side. 首先,请记住,这一切都在客户端。 So long as you trust the JSON (it came from your server or it is controlled alongside the application itself), then you can use it. 只要您信任JSON(它来自服务器或与应用程序本身一起受控制),就可以使用它。 That doesn't completely rule out some trojan inserting malicious rules, but I don't think botnets have learned to play D&D yet. 这并不能完全排除某些木马程序插入恶意规则,但是我认为僵尸网络还没有学会玩D&D。

To literally avoid eval and provide some modicum of security, you can use new Function . 为了从字面上避免评估并提供某种程度的安全性,可以使用new Function It takes a list of argument names followed by the function body, allowing you a large amount of control over how the function is defined and where it can be referenced from. 它采用参数名称列表,然后是函数主体,使您可以大量控制函数的定义方式以及可以从何处引用函数。 You only need to store the body in the JSON file, allowing you to largely control the parameters and make it difficult to assign to the global scope, minimizing your attack surface (such as it is) quite a lot. 您只需要将主体存储在JSON文件中,就可以在很大程度上控制参数并使其难以分配给全局范围,从而极大地减少了攻击面。

If you want to have fun with this and now your rules will largely be mathematical, you may consider using a tool like pegjs to generate a parser for your rules. 如果您希望以此为 ,现在您的规则基本上是数学的,则可以考虑使用诸如pegjs之类的工具来为规则生成解析器。 Calculators are one of the classic introductions to parsers and compilers, so this could be an opportunity to play with some fun tech. 计算器是解析器和编译器的经典介绍之一,因此这可能是一个使用一些有趣的技术的机会。 The rules and parsers built by pegjs are very easy to use in a JS project (I have an example using PegJS and ES6 via Babel ). 由pegjs构建的规则和解析器在JS项目中非常易于使用(我有一个通过Babel使用PegJS和ES6的示例 )。

I did a quick google search and found two options - http://mathjs.org and http://jsep.from.so 我做了一个快速的谷歌搜索,发现了两个选择-http : //mathjs.orghttp://jsep.from.so

btw. 顺便说一句 writing your own parser is not that difficult. 编写自己的解析器并不困难。 You may be able to write one that's sufficient for your purpose in less than 100 lines of code 您也许可以用不到100行的代码编写一个足以满足您的目的的代码

One solution to your problem is to use sandboxed iframes (current supported by all major browsers 解决您的问题的一种方法是使用沙盒iframe所有主要浏览器均支持该功能)

You run user code on a separate page, with limited priviliges, in such a way that the code does not interfere with the rest of the application. 您可以在权限有限的单独页面上运行用户代码,以使代码不会干扰应用程序的其余部分。 You can communicate with the sandboxed page using postMessage() and window.onmessage . 您可以使用postMessage()window.onmessage与沙盒页面进行通信。

There are two options as I see it. 我看到有两个选择。 One, if you 100% want to define the function in .json, you will need to parse. 第一,如果您100%想在.json中定义函数,则需要进行解析。 JSON does not allow functions, so you need to store the function as a string and eval it. JSON不允许使用函数,因此您需要将函数存储为字符串并进行评估。

The better way would be to also provide a config.js ability. 更好的方法是还提供config.js功能。 Perhaps the .json would have a "configUrl": property, and then expose well known apis, eg RPGHelper.setModifer(someFunction) that you can call from inside the config.js file. 也许.json将有一个"configUrl":属性,然后暴露众所周知的API,如RPGHelper.setModifer(someFunction)您可以从config.js文件内调用。 The user is then free to define whatever arbitrary logic there. 然后,用户可以自由定义那里的任意逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用用户定义的相等函数在Javascript中创建一组用户定义的对象? - How to create a Set of user-defined objects in Javascript with a user-defined equality function? 如何在javascript中调用窗口对象的用户定义函数 - how to call user-defined function of a window object in javascript 是否可以在sqlite中创建一个javascript用户定义的函数 - Is it possible to create a javascript User-defined function in sqlite 使用PHP和JavaScript创建带有用户定义字段的表单 - Creating a form with user-defined fields using PHP and JavaScript 是否可以在 JavaScript 中使用用户定义的名称创建变量? - Is it possible to create a variable using user-defined name in JavaScript? 如何使用e.target访问用户定义的属性值-javascript / react.js - How to access the user-defined attribute value using e.target - javascript/react.js 使用用户定义的函数时地图消失 - Map disappears when using a user-defined function 如何在打字稿或JavaScript中将用户定义的日期时间转换为毫秒? - How to convert user-defined datetime to milliseconds in typescript or javascript? 如何在 Javascript 中设置自定义时间并增加 2 小时? - How to set user-defined time in Javascript and add 2 hours to it? 如何在Javascript中JSON.stringify用户定义的类? - How to JSON.stringify a user-defined class in Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM