我正在努力防止恶意注入网站。我这样做的方式是创建一个"修剪" URL的任何额外部分都会使其成为非法的。
为了使网址合法,必须遵循以下格式:
(任何东西)(几个特定的路径前身之一)(特定页面)
例如,假设您的路径前辈是......
["服务","服务/城市","特价","特价/限制/"]
一些示例输入和结果:
www.fake.com/services/home - > (合法,无修剪) - > www.fake.com/services/home
www.fake.com/services/city/nyc - > (合法,无修剪) - > www.fake.com/services/city/nyc
www.fake.com/services/city/nyc/fakeinjection.txt - > (非法) - > www.fake.com/services/city/nyc
www.fake.com/specials/limited/california/fake/fake/fake.bak - > (非法) - > www.fake.com/specials/limited/california
所以我编写了以下正则表达式以仅匹配输入URL的合法部分:
/.*(services|services\/city|specials|specials\/limited)\/[^\/]*/gi
问题在于它并不总是捕获最大可能的匹配,因此无意中修剪过多。例如:
www.fake.com/services/city/nyc - > (应该是合法的,不应该修剪) - > www.fake.com/services/city /
我知道为什么会发生这种情况。我相信它正在捕捉它看到的第一件事并与之相匹配。但我需要强迫它采取最大的可能,只在必要时修剪。我认为"贪心" flag会帮助做到这一点,但事实并非如此。
有人可以就解决方案提供一些指导吗?非常感谢。
(PS。如果它有所不同,我使用的语言是javascript)
答案 0 :(得分:2)
如果你有一个非锚定的交替小组,你应该先放置最长的替代方案。在任何NFA正则表达式中,匹配的第一个分支停止处理交替组并继续使用后续模式。
所以,你可以使用
/.*(services\/city|specials\/limited|services|specials)\/[^\/]*/
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^
请参阅regex demo
如果您使用可选组手动创建模式以减少回溯,则可以进一步增强此列表:
/.*(services(?:\/city)?|specials(?:\/limited))\/[^\/]*/
甚至
/.*(s(?:ervices(?:\/city)?|pecials(?:\/limited)))\/[^\/]*/