2012-06-01 47 views
4

情况是这样的:我有一些创建交互式对话的JavaScript(并通过动态元素创建以漫画的形式显示它......很有趣)。该页面允许用户调整设置,改变脚本产生的对话。作为一个理论示例,其中一个复选框可以是“使用cussing”,如果此复选框被选中,脚本只会将cuss单词添加到返回的字符串中。 oK,够简单。乐趣。Javascript:处理用户生成脚本的最佳方式

它目前只使用一个模板(“漫画”具有非常具体和尖锐的目的)来生成对话;这个模板被硬编码到JavaScript中。我希望用户能够创建自己的模板,然后将其转换为与硬编码版本一样执行的脚本,并且可以通过复选框选项进行控制。 编辑:为了澄清,用户不直接编写脚本。他们编写一个表示(我现在正在考虑使用JSON),当其他人使用模板打开页面时,页面会将其转换为脚本并执行它。

这提出了一些问题。最明显的是恶意用户的攻击。 编辑:虽然用户不会自己编写脚本,但由于所有的客户端都可以轻松地看到我的解析脚本,并且可以找出如何插入某些东西。虽然并不太担心这一点。 结束编辑。我确定有一些标准的方法来处理这个问题,并且因为目前没有交互服务器端 - 所有的客户端 - 我主要关心的是这样的用户不能通过分享他的不好的版本来伤害另一个用户的体验。现在,我简单地通过全局替换不在一组中的所有字符来剥离字符串:

str.replace(/[^a-zA-Z...]/g,'')

另一个问题是如何将他们的模板提供给他人欣赏的页面。正如我所说的,没有服务器端的交互,我想保持这种方式。我不想创建MySQL表格等来存储他们的模板。不幸的是,这意味着我能想到的唯一可行的方法是将它们的模板放在URL的查询字符串中。讨厌的,那个。而且这确实会对字符长度施加限制 - 如果我的阅读正确,只需要2000个字符就可以兼容较旧的IE。 (我也想过生成一个HTML文件的文本,他们可以复制n贴,保存为这样,主机的地方,并发送地址到我的网页的URL,然后加载到一个iFrame ......哈是的,不是用户友好型的 - 既包括文件类型的保存,它们可能从未保存过以前的文件类型,也考虑如何托管文件 - 并且会产生更大的安全问题。)

第三个问题是一旦页面从他们那里收到了模板,使其变得安全,并将其转换为脚本,我应该如何执行该脚本?自从我第一次开始使用Javascript以来,我听说eval是邪恶的,所以我避免使用它。显然做new Function(txt)是一样邪恶的(虽然我已经做了很多次)。我愿意接受这些邪恶的主张......但是还有什么替代方案?我搜索了谷歌,最接近我的情况,我能找到的是this StackOverflow question, involving remote code。接受的答案建议使用textContent设置为脚本字符串动态创建脚本标记。这对我来说也是最好的解决方案吗?

摘要

我需要访问用户生成的文本(优选不将其存储服务器端),它解析成的Javascript同时避免攻击,然后用一些替代eval()执行它。

  1. 将它们的模板作为查询字符串存储在URL中,然后可以共享该模板,这是将模板获取到页面的唯一方法?
  2. 我应该注意哪些安全漏洞,以及防范恶意用户的标准方法是什么?
  3. eval有什么替代方法可以执行未硬编码到脚本中的远程检索代码?
+0

即使IE9具有〜2047个字符的URI(例如GET)限制。 – 2012-06-01 20:59:04

+3

而不是存储“脚本”,存储声明的东西 - 例如JSON表示模板/操作 - 然后应用只执行“可信”代码。然而,考虑到jsfiddle.net运行“不可信代码”,所以......(正如前面提到的,这个问题出现在“模仿”风格的攻击中,它比以前更有保护性) – 2012-06-01 21:00:31

+0

将三个问题组合成一个并不是要如何使用SO。如果你分解它,这个问题对别人更有用。您可以缩短每个问题的时间,甚至参考以前的问题 –

回答

3

正如@pst所说,使用模板特征(和参数)的JSON表示,并且只运行可信代码。

也许像

{ 
    border: { color: '#BADA55' }, 
    layout: { columns: 2, rows: 4 } 
} 

,然后只是一个循环,处理程序数组,一个switch...case级联或类似解析它。

压缩了一下,这可能适合2000字符以下的相当详细的模板。


的jsfiddle安全地从不同域名的iframe服务运行不受信任的代码,因此,如果这是一个选项,你真的要EVAL一些不可信的代码,只要做到这一点。如果你坚持防止“受伤的经历”,你最终还是会做出陈述式的陈述(或试图完美地消毒,直到你意识到你不能)。

+0

就是这样,不要让用户创建脚本,让他们创建数据(JSON),并正确执行它,确保您不会评估任何内容。 –

+2

我不认为jsfiddle是一个很好的比较。在JS小提琴中,您必须允许用户输入代码。在OP的情况下,用户不需要输入实际的代码 –

+0

我同意。我只是预先通过一个普遍提供的“安全评估”的例子 – bkconrad