【问题标题】:Is this JavaScript code safe?这个 JavaScript 代码安全吗?
【发布时间】:2023-03-26 19:07:01
【问题描述】:

我在网上找到了以下JS。

这是一个获取url参数值的函数。

function get_url_param(param) {
  param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+param+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec(window.location.href);
  if( results == null )
    return '';
  else
    return results[1];
}

但是,当我看到 exec() 函数时,我总是会想:Eeek!

所以我的问题是:它安全吗?

赌注:如果您认为此功能很糟糕并且有更好的选择,请不要犹豫分享:)

上面的函数使用的是真实的url,但我只需要解析一个包含url的字符串。

【问题讨论】:

  • exec 调用不执行代码。我不明白为什么这会不安全。
  • 对我来说似乎很安全,如果您不喜欢 .exec,只需更改它

标签: javascript url-parameters


【解决方案1】:

您在函数中看到的.exec() 不是窗口,而是RegExp 对象。

所以很好用。

【讨论】:

  • 是的,它只是regex(正则表达式)方法的一种方法。只有看到“eval()”时才应该担心
  • @Neal:太好了!不能太偏执......实际上你可以,但那是另一个故事:P
【解决方案2】:

我不会将正则表达式 execeval 混淆。有点笨拙,但应该可以。

【讨论】:

    【解决方案3】:

    Regexp#exec 是安全的,虽然不是一个很好的界面。

    赌注:如果您认为此功能很糟糕并且有更好的选择,请不要犹豫分享:)

    耶 :-)

    param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    

    这不使用global 正则表达式,因此您只需替换每个括号的一个实例; field[][] 不起作用。此外,您不需要字符组...param.replace(/\[/g, '\\[') 会起作用。或者,非正则表达式替换习语,param.split('[').join('\\[')

    然后:

    var regexS = "[\\?&]"+param+"=([^&#]*)";
    

    您没有转义足够多的字符,无法将它们放入正则表达式并让它们表示它们的字面意义。请参阅this question 以获得更防水的替代方案。

    无论如何,这种正则表达式黑客仍然不是解析 URL/查询字符串的好方法。这不能正确处理 ;%-encoding 或 + 空间,它可能会在 URL 中的其他地方出现类似参数。

    相反,让我们首先自己获取查询字符串。如果您有链接或位置对象,则可以从 .search 属性中获取它。如果你只有一个字符串 URL,你可以把它变成一个链接对象来可靠地得到这个:

    function getQueryString(url) {
        var a= document.createElement('a');
        a.href= url;
        return a.search;
    }
    

    现在您可以通过删除前导 ?,拆分 &;,然后将 URL 解码的结果放入 JS 对象来解析它:

    function parseQuery(query) {
        var lookup= {};
        var params= query.slice(1).split(/[&;]/);
        for (var i= 0; i<params.length; i++) {
            var ix= params[i].indexOf('=');
            if (ix!==-1) {
                var name= decodeURIComponent(params[i].slice(0, ix));
                var value= decodeURIComponent(params[i].slice(ix+1));
                if (!(name in lookup))
                    lookup[name]= [];
                lookup[name].push(value);
            }
        }
        return lookup;
    }
    

    这使得查找参数变得容易:

    var url= 'http://www.example.com/?a=b&c=d&c=%65;f[]=g#h=i';
    var pars= parseQuery(getQueryString(url));
    
    alert(pars.a);      // ['b']
    alert(pars.c);      // ['d', 'e']
    alert(pars['f[]']); // ['g']
    alert('h' in pars); // false
    

    如果您不需要为一个参数读取多个值,您可以只使用lookup[name]= value 而不是if...[]...push 舞蹈,以在查找而不是列表中返回单个字符串值。

    【讨论】:

    • 哇。谢谢!我特别发现 var a= document.createElement('a'); smart :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    相关资源
    最近更新 更多