正则表达式和编码攻击-PHP内部编码是如何工作的?

正则表达式和编码攻击-PHP内部编码是如何工作的?,php,regex,utf-8,character-encoding,Php,Regex,Utf 8,Character Encoding,我使用UTF-8正则表达式来获取Content-Type:header行的部分内容,因为我习惯于将服务器配置为一致使用UTF-8 // example type, actually this will be negotiated from request `Accept:` header line. $content_type = 'TeXt/HtMl'; preg_match('~^([\w-]+\*?)/([\w-]+\*?)$~ui', $content_type, $matches);

我使用UTF-8正则表达式来获取Content-Type:header行的部分内容,因为我习惯于将服务器配置为一致使用UTF-8

// example type, actually this will be negotiated from request `Accept:` header line.
$content_type = 'TeXt/HtMl';
preg_match('~^([\w-]+\*?)/([\w-]+\*?)$~ui', $content_type, $matches);

考虑从基于子模式匹配构建的文件系统路径加载类。

是否有任何可以想象的方法通过编码攻击来注入一些“/../”? 一般来说,内部编码是如何工作的?在PHP代码中处理数据时,我是否需要关心请求的编码字符集,或者转换是否自动可靠地工作?编码安全性还需要记住什么?如何确保在未知系统上运行的已部署代码中进行编码

编辑: 如评论中所述,一些进一步的代码可能类似于:

m1 = strtolower($matches[1]);
m2 = strtolower($matches[2]);
include_once "/path/to/project/content_handlers/{$m1}_{$m2}";
备注:我的问题是要更笼统一些。让我们考虑一些场景:PHP脚本是用UTF-8编码的。服务器的文件系统以字符集A编码。客户端以编码B处理要发送的请求。是否存在潜在的风险,即接受的头是以preg_*函数无法识别某些“/../”父目录而不是文件系统的方式写入的?问题不限于示例中的特定正则表达式。如果不采取进一步的预防措施,攻击者是否能够在文件系统中包含任意文件

备注2:在提供的示例中,我不能依赖http_协商_内容_类型,因为它不确定目标服务器上是否安装了pecl_http。还有一个脚本化的polyfill。再次强调:这不是一个特定案例的问题。我想学习如何处理甚至被操纵的客户端编码


备注3:这里讨论了SQL编码攻击的一些类似问题:然而,我的问题是关于文件系统编码的。可能会发生类似的情况吗?

我将大胆地说,您的代码将有效地防止恶意子字符串。如果有人试图偷袭一系列角色,他们将被preg_match击倒。使用锚定和角色类不会给你任何回旋的空间。图案很漂亮,很严格

请注意:

\w已经不区分大小写,因此不需要i pattern修饰符。 您的捕获组存储在$matches[1]和$matches[2]中。完整字符串匹配的格式为$matches[0]。 代码:

输出:

array (
  0 => 'TeXt/HtMl',
  1 => 'TeXt',
  2 => 'HtMl',
)

这完全取决于下面几行代码。请更新您的帖子,包括它们。如前所述,$matches[0]和$matches[1]用于构建文件系统路径。基本的问题是,人们是否可以普遍依赖preg_match'~whatever~u'。如果这已经是安全的,我不想要不必要的开销。您将如何处理$matches是很重要的。你得给我们看看。一般来说,不,这是不安全的。@mickmackusa是的,*ist可选通配符和不敏感匹配是必需的,因为根据规范,“text/html”、“text/html”和“text/html”都是等效的,即使第一个是推荐的,并且几乎每个用户代理都遵守。很好的一点-这是正确的。是的,当然,在我的代码中,我使用了子模式的索引1和索引2。在评论的压力下,快速提供一些手写的例子是一个错误。我刚刚通过编辑问题来纠正这一点,以防止误导性的答案。我的问题是更一般的:当用户代理发送一些例如中文编码的请求时,PHP是否在内部使用UTF-8或其他预配置的编码,并且是否有任何带有u修饰符的preg_*函数是安全的?使用unicode模式修饰符,您将能够很好地处理多字节字符。你的意思是:?是的。有一些众所周知的sql注入场景,其中sql命令中包含的清理字符串无法正常工作,因为数据库会识别某些引用,而清理功能由于不同的mb编码而无法识别这些引用。我们最初根本不是在讨论sql,对吗?如果要在查询中使用用户提供的数据,那么预处理语句是正确的方法。对,这个问题不是关于SQL,而是关于文件系统编码的类似潜在风险。SQL ecoding攻击只是一个众所周知的比较场景。
array (
  0 => 'TeXt/HtMl',
  1 => 'TeXt',
  2 => 'HtMl',
)