将用户定义的表达式与std::regex
一起使用是否安全(例如,用于服务器端搜索)?标准库是否对折断表达式的安全性有任何保证?
答案 0 :(得分:2)
该标准要求当传递的正则表达式无效时,实现会引发错误。
explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
要求:
p
不能为空指针。抛出:
regex_error
p
不是有效的正则表达式。效果:构造一个类basic_regex的对象;对象的内部有限状态机由长度为
charT
的{{1}}数组中包含的正则表达式构造而成,该数组的第一个元素由char_traits<charT>::length(p)
指定,并根据标志{{1 }}。确保:
p
返回f
。flags()
返回表达式中标记的子表达式的数量。
甚至还有table详述了可能的各种错误。
只要您不传递空指针,从用户提供的字符串创建正则表达式时就应该没有未定义的行为。
请注意,任何实际的实现当然都可能仍然存在可能导致安全漏洞的错误。该标准显然也不能通过提交一个非常复杂的/自引用的正则表达式来保证恶意用户无法对您的系统进行DoS,该正则表达式会产生过多的匹配项,占用过多的内存/ CPU等,因此您必须考虑一下你自己。但是,如果您只是担心无效的正则表达式是否可以自由导致UB,答案是“不,您还好”。
答案 1 :(得分:2)
基本上不是。这是不安全的。可以精心设计出合法的正则表达式,这些计算需要花费非常长的时间才能完成-导致拒绝服务。
来自ReDoS下的维基百科
正则表达式拒绝服务(ReDoS)[1]是一种算法复杂性攻击,它通过提供耗时很长的正则表达式来产生拒绝服务。该攻击利用了以下事实:大多数正则表达式实现都有指数时间(最坏情况下的复杂度):所花费的时间可能相对于输入大小成指数增长。因此,攻击者可以通过提供这样的正则表达式来减慢速度或变得无响应,从而导致程序花费大量时间进行处理。
答案 2 :(得分:0)
C ++标准定义了正确行为的含义。即使在抛出异常的函数的情况下,标准也定义了抛出哪些函数,将抛出哪些异常以及在何种情况下会导致此类异常的抛出。这样的代码具有标准明确定义的行为。
该标准没有也不能指定如果实现针对标准所定义的行为(即:“已损坏”)而发生的情况。如果该标准定义了这种行为,那么根据定义,实现将不会违反该标准。这样它们就不会再被“破坏”了。
因此,正则表达式实现是否能够避免由未经消毒的外部提供的字符串引起的病理行为,是实现质量的问题,而不是标准定义的行为。