0

我有一个字符串,我需要确保它只包含一个正则表达式而不包含 javascript,因为我正在使用该字符串创建一个新脚本,因此 javascript 片段会带来安全风险。

具体场景:

  1. mozilla 插件中的 JS 通过 HTTPrequest 将配置加载为 json (json contains {"something": "^(?:http|https)://(?:.*)"}
  2. JS 创建一个 pac 文件(代理配置脚本),该文件使用配置中的“某事”正则表达式

任何想法如何在不破坏其中的正则表达式的情况下转义字符串?

4

2 回答 2

0

It seems that most of the standard JavaScript functionality is available (source), so you can just do:

try {
    RegExp(json.something+'');
    pacFile += 'RegExp(' + JSON.stringify(json.something+'') + ')';
} catch(e) {/*handle invalid regexp*/}

And not worry, because a RegExp("console.log('test')") will only produce a valid /console.log('test')/ regexp and execute nothing.

于 2014-08-28T18:25:27.930 回答
0

您可以使用正则表达式来拆分 JavaScript 正则表达式。

然后,您应该将正则表达式转换为词法上更简单的 JavaScript 子集,从而避免所有非上下文无关的怪异/含义以及输入正则表达式中的任何不规则性。

var REGEXP_PARTS = "(?:"
    // A regular character
    + "[^/\r\n\u2028\u2029\\[\\\\]"
    // An escaped character, charset reference or backreference
    + "|\\\\[^\r\n\u2028\u2029]"
    // A character set
    + "|\\[(?!\\])(?:[^\\]\\\\]|\\\\[^\r\n\u2028\u2029])+\\]"
    + ")";

var REGEXP_REGEXP = new RegExp(
    // A regex starts with a slash
    "^[/]"
    // It cannot be lexically ambiguous with a line or block comemnt
    + "(?![*/])"
    // Capture the body in group 1
    + "(" + REGEXP_PARTS + "+)"
    // The body is terminated by a slash
    + "[/]"
    // Capture the flags in group 2
    + "([gmi]{0,3})$");

 var match = myString.match(REGEXP_REGEXP);

 if (match) {
   var ctorExpression =
       "(new RegExp("
         // JSON.stringify escapes special chars in the body, so will
         // preserve token boundaries.
         + JSON.stringify(match[1])
         + "," + JSON.stringify(match[2])
       + "))";
   alert(ctorExpression);
 }

这将导致表达式位于 JavaScript 的一个易于理解的子集中。

上面的复杂正则表达式不在TCB中。唯一需要正确运行以保持安全性的部分是ctorExpression包括使用JSON.stringify.

于 2014-08-28T18:02:47.543 回答