V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
qnsh
V2EX  ›  JavaScript

JavaScript eval()安全问题

  •  
  •   qnsh · 2015-07-28 17:31:41 +08:00 · 6776 次点击
    这是一个创建于 3166 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码 eval('(' + Text + ')') 存在注入问题,有什么方法可以替代或避免该问题吗?

    25 条回复    2015-07-29 10:54:37 +08:00
    zythum
        1
    zythum  
       2015-07-28 17:35:56 +08:00
    保证text内容是你可控的。
    FrankFang128
        2
    FrankFang128  
       2015-07-28 17:36:17 +08:00
    不相信外部输入即可。

    你为啥要用 eval()?
    这可能是一个 XY 问题。
    morethansean
        3
    morethansean  
       2015-07-28 17:37:57 +08:00
    不要使用 eval。
    你应该问有没有方法不使用 eval 实现你的具体需求……
    如果这就是你的具体需求……假设这个需求真的不奇怪,那只能自己过滤了啊……
    lichao
        4
    lichao  
       2015-07-28 17:41:56 +08:00
    @FrankFang128

    例如 JSON with Padding 的时候
    qnsh
        5
    qnsh  
    OP
       2015-07-28 17:44:19 +08:00
    @morethansean @FrankFang128 我也不想用eval,问题是之前的代码用了,我要修改这这个方法,想找个替代方案。
    FrankFang128
        6
    FrankFang128  
       2015-07-28 18:12:41 +08:00
    @lichao jsonp 吗?不需要 eval 的呀,不是回调么?
    edire
        7
    edire  
       2015-07-28 18:49:36 +08:00
    如果是json的话,JSON.parse() 可将 json形式的字符串转换为js对象。
    zythum
        8
    zythum  
       2015-07-28 18:58:02 +08:00
    @FrankFang128 有啥区别.... 回调数据是破坏性代码不一样....
    FrankFang128
        9
    FrankFang128  
       2015-07-28 18:59:41 +08:00
    @zythum 回调不用 eval 嘛,我写几年JS都没用几次 eval
    zythum
        10
    zythum  
       2015-07-28 19:04:45 +08:00
    @FrankFang128
    jsonp_callback( { I_am_xss: (function () {alert(1)}()) } );
    FrankFang128
        11
    FrankFang128  
       2015-07-28 20:32:23 +08:00 via Android
    @zythum jsonp mimetype 设为 text/html ,然后这段回调不会执行的
    bramblex
        12
    bramblex  
       2015-07-28 21:34:06 +08:00 via Smartisan T1
    这是你的问题,为什么你eval的东西里面会有用户输入?你需要用户给你写代码吗?

    如果没有,那么你的用户怎么注入你?入侵你服务器来注入吗?
    sneezry
        13
    sneezry  
       2015-07-28 21:37:13 +08:00
    不要用eval、new Function,以及不要在setTimeout和setInterval里将字符串解析成代码运行
    bramblex
        14
    bramblex  
       2015-07-28 23:56:47 +08:00 via Smartisan T1
    @sneezry 动态加载代码的时候eval的效率比插节点高的得多,而且可以并行加载!
    sneezry
        15
    sneezry  
       2015-07-29 00:01:19 +08:00
    @bramblex 安全问题比效率问题优先级高。
    bramblex
        16
    bramblex  
       2015-07-29 02:17:09 +08:00
    @sneezry

    所以你的业务是多奇葩需要 eval() 用户输入?你难道需要用户给你写代码?虽然我还真有想法做一个类似的网站。

    出现这种情况只能说明你的程序设计本身有问题,而不是eval有问题。如果你js里面要是硬要包含一段未做过滤的用户输入,那么无论你用eval()还是插入节点都会产生问题。eval产生的绝大多数所谓的问题,都是因为低端程序员滥用而导致的,而不是eval本身有问题,这一点上就跟c指针或者goto语句一样。

    其实编程规范里面禁止用eval,这不过是就为了在团队协作的时候防猪队友而已,你不能要求你每一个队友都跟你一样能驾驭eval(),所以干脆禁止写eval。

    不过eval()的灵活性让很多不可能编程可能。举一个简单的例子,类似c++的namespace,也可以在javascript里模拟实现了。
    magicyu1986
        17
    magicyu1986  
       2015-07-29 02:22:37 +08:00
    'use strict' 会好一点。

    另外很多时候eval都有替代方法。
    jugelizi
        18
    jugelizi  
       2015-07-29 08:47:36 +08:00
    确实啊
    eval执行的代码几乎是由服务器返回的为什么怕安全呢?
    sneezry
        19
    sneezry  
       2015-07-29 08:50:12 +08:00 via iPhone
    @bramblex 您这想法不对,eval可不像this,我们说this是非常棒的东西,但很多人驾驭不好,可是我们从来没说过要去禁用它。eval里的代码我们也基本不会设计成让用户输入,但您必须承认使用eval有内在的风险。Google对Chrome扩展和应用的开发明确禁用了eval,Google在多处文档,包括html5rocks中也多次强调不要用eval,这不是您能不能驾驭代码的问题,用户的网络环境不是您一个前端程序员能控制的。
    sneezry
        20
    sneezry  
       2015-07-29 08:51:31 +08:00 via iPhone
    @jugelizi 就是怕用户被劫持啊,而且一旦服务端出现什么bug会连带前端一起遭殃
    jugelizi
        21
    jugelizi  
       2015-07-29 09:02:14 +08:00
    @sneezry 这完全是一个信任边界的问题,好比我们认为国内的浏览器不会把cookie发送到自己的服务器一样,当eval执行服务器返回代码我们要做的就是保证服务器返回的是我们可控的。
    sneezry
        22
    sneezry  
       2015-07-29 09:18:00 +08:00 via iPhone
    @jugelizi 您说的对,是信任问题。如果能保证是最完美的情况,当然也是正常的情况,但不可否认总是有小概率个别情况。安全问题真的不能小视,我们很难把全部情况都考虑到。
    accps115202
        23
    accps115202  
       2015-07-29 09:22:47 +08:00
    var json =(new Function("","return "+texts))(); --可以用这个替代
    bramblex
        24
    bramblex  
       2015-07-29 10:00:35 +08:00
    @sneezry 首先,我还真不是“前端程序员”……

    1. ==============================================
    上面所谓的安全问题出在那里?所谓的服务器bug是是什么问题?

    说白了就是代码和数据耦合。因为你让服务器去给你生成了一段代码,然后执行。

    为什么你需要让服务器给你生成代码?因为你你把数据插进了代码里面,所以需要才需要让服务器给你生成代码。

    最后产生什么?你所说的“安全问题”。但这些问题只是因为程序设计的问题,而不是eval的问题。

    2.==============================================
    eval还要执行自己生成的代码。为啥要自己生成代码(用js生成js代码)?当然是实现原生JS不能实现的功能啊。

    比如你给我实现一下,如何重命名一个函数。比如一个 (function(){}) 我要把它变成命名的 (function name(){})
    zythum
        25
    zythum  
       2015-07-29 10:54:37 +08:00
    @FrankFang128 ... 只会有个warnning... 不过我们跑题了... 就此打住吧。 : )

    给po主的结论是.

    如果你的代码就是个内部工具。或者内部系统。对安全没有要求的。请无视这个。

    如果需要考虑安全问题:

    1. 要么确保你的text的你可信任。
    2. 要么给text的数据做数据结构解析,或者安全性检测(字符串层面的)。(JSON2,JSON3 对与JSON.parse 的 低级浏览器就是这么做的)。然后再eval.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5911 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 02:09 · PVG 10:09 · LAX 19:09 · JFK 22:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.