如何使用JavaScript/正则表达式从字符串中找到"<script>"标签

19

我需要验证传入的字符串是否含有文本<script

string a = "This is a simple <script> string";
现在,我需要写一个正则表达式来判断这个字符串是否包含一个<script>标签。

最终我写出了类似这样的东西:<* ?script.* ?>

但是问题在于,输入的字符串可能以以下方式包含脚本:

string a = "This is a simple <script> string";
string a = "This is a simple < script> string";
string a = "This is a simple <javascript></javascript> string";
string a = "This is a simple <script type=text/javascript> string";
因此,正则表达式应该检查以 < 开始的标签,然后检查 script

1
请阅读这个链接 https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 对于这里可能非常相关。 - Prinzhorn
6个回答

53
/<script[\s\S]*?>[\s\S]*?<\/script>/gi
@bodhizero的回答:<[^>]*script在以下情况下会错误地返回true
// Not a proper script tag.
const a = "This is a simple < script> string"; 

// Space added before "img", otherwise the entire tag fails to render here.
const a = "This is a simple < img src='//example.com/script.jpg'> string";

// Picks up "nonsense code" just because a '<' character happens to precede a 'script' string somewhere along the way.
const a = "This is a simple for(i=0;i<5;i++){alert('script')} string";

这是一个优秀的资源,用于构建和测试正则表达式


如果使用HTML编码,那该怎么办呢?因此,字符串也必须根据以下正则表达式进行验证:%3Cscript[\s\S]?%3E[\s\S]?%3C/script%3E/gi还有一件事,“i”用于不区分大小写。 - Pankaj Goyal
当我在regex101.com上尝试使用这个正则表达式时,它会产生一个“灾难性的回溯”错误。 - Randall Coding

4

试试这个:

/(<|%3C)script[\s\S]*?(>|%3E)[\s\S]*?(<|%3C)(\/|%2F)script[\s\S]*?(>|%3E)/gi

这个答案怎么比Let Me Tink About It的更好? - trusktr

4

使用这个:

const re = /<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/g

使用方法如下:

const html = `
  ...
  
    <script type="text/javascript">
        alert('1');
    </script>

    <div>Test</div>

    <script type="text/javascript">
        alert('2');
    </script>

  ...
`

const re = /<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/g

const results = html.match(re)

console.log(results) // an array containing each script tag.

在此处查看并了解特定的正则表达式:

https://regexr.com/5od96

Regexr网站是最有用的正则表达式网站!将鼠标悬停在正则表达式的任何部分上,它都会告诉您相关信息以及更多内容。还可以保存和探索其他人创建的正则表达式。


非常感谢。这节省了我很多时间。对于我所有的用例来说,这是最好的、唯一可行的解决方案。 - Eduard Void

3
我推荐的基于正则表达式的解决方案如下:
Regex rMatch = new Regex(@"<script[^>]*>(.*?)</script[^>]*>", RegexOptions.IgnoreCase & RegexOptions.Singleline);
myString = rMatch.Replace(myString, "");

这个正则表达式可以正确识别并移除以下字符串中的脚本标签:

<script></script>
<script>something...</script>
something...<ScRiPt>something...</scripT>something...
something...<ScRiPt something...="something...">something...</scripT something...>something...

此外,它不会匹配以下任何无效的脚本字符串:

< script></script>
<javascript>something...</javascript>

嗨,Jason,你会如何在这个正则表达式中使用负向先行断言呢?即:不是这个。 - yardpenalty.com
糟糕!您和您的点赞者刚刚被...<scr<script></script>ipt>alert("p0w3nd!")</script>攻击了。 - Zectbumo
2
#Zectbumo 我认为你的字符串应该被验证为真。只有有效的脚本标签才会被浏览器解析为JavaScript。格式不正确的字符串将被视为文本。因此,你的字符串在任何方面都不会有危险。 - Jason Williams
抱歉,您忘记了换行符,如果输入包含换行符,则此正则表达式将无法注册:<script>tra la\nla</script>。 - revelt
那不是JavaScript代码,原帖作者要求JavaScript全部大写。 - trusktr

2
一个否定的字符类在这里非常有用。
<[^>]*script

感谢bodhizero。我也找到了类似的东西,(%3C* | <)[^ *]?脚本 - Ajay Kulkarni
str.includes('<script') - Muhammad Umer

-2

我觉得这个对我肯定有效。

var regexp = /<script+.*>+.*<\/script>/g;

如果在脚本标签之间有换行符,则无法正常工作!此外,开放脚本中的加号没有意义,您在那里说“一个或多个字母t”。您可能想要放置括号,但这是一个有缺陷的正则表达式。 - revelt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接