目录
什么是零字节,为什么重要?
陷阱1:文件操作中的意外截断
陷阱2:文件上传中的安全风险
陷阱3: strcmp和字符串比较的问题
陷阱4:正式表达式的不当行为
一般最佳实践
首页 后端开发 php教程 用零字节和PHP中的字符串终止解决常见的陷阱

用零字节和PHP中的字符串终止解决常见的陷阱

Jul 28, 2025 am 04:42 AM
PHP Strings

当与C扩展或系统调用接口时,null字节(\ 0)可能会导致PHP中的意外行为,因为C将\ 0视为字符串终端,即使PHP字符串是二进制安全并保留了全长。 2。在文件操作中,包含诸如“ config.txt \ 0.php.bak”之类的null字节的文件名可以截断为“ config.txt”,从而导致文件访问不正确或安全风险。 3。在文件上传期间,攻击者可以利用$ _post ['filename']中的null字节来绕过扩展检查,例如,“ shell.php \ 0.jpg”被保存为“ shell.php”。 4。纯php中的字符串比较(===,strCMP)正确处理null字节,但是基于C的扩展或数据库驱动程序可能会截断字符串,冒着数据完整性的风险。 5。正则表达式可以与null字符部分匹配,除非用\ a和\ z正确锚定,否则必须在处理前检查输入以获取\ 0。 6.最佳实践包括使用str_replace(“ \ 0”,',$输入)过滤零字节,或使用Basename(),realpath()和filter_input()和filter_input()拒绝它们,验证所有用户输入,避免使用系统呼叫或SQL中的直接字符串插值,以及使用准备好的语言来确保安全的语言来确保安全。始终将零字节视为潜在的危险输入,并明确处理它们,以防止截断和安全漏洞。

用零字节和PHP中的字符串终止解决常见的陷阱

使用PHP中的字符串通常感觉很简单 - 直到您遇到涉及null字节\0 )和字符串终止的边缘案例,尤其是在与C扩展名,文件操作或用户输入的连接时。尽管PHP比低级语言更灵活地处理字符串,但这些问题仍然会导致意外的行为,安全漏洞或数据截断。这是理解和避免最常见的陷阱的方法。

用零字节和PHP中的字符串终止解决常见的陷阱

什么是零字节,为什么重要?

null字节\0 )是一个字符,其ASCII值为0。在C风格的字符串中,它标志着字符串的末端。但是,PHP字符串是二进制安全的,这意味着它们可以包含空字节并仍然保留全长。当PHP将字符串传递到C函数(例如扩展或系统调用中的\0 )时就会出现问题。

例如:

用零字节和PHP中的字符串终止解决常见的陷阱
 $ string =“ Hello \ 0world”;
Echo strlen($ string); //输出:11

即使使用零字节,PHP也知道字符串长11个字符。但是,如果该字符串传递给了C函数,则可以期待一个无效的字符串,则只会看到"hello"


陷阱1:文件操作中的意外截断

当使用file_get_contents()fopen()之类的函数时,就会发生最常见的问题之一。

用零字节和PHP中的字符串终止解决常见的陷阱
 $ filename =“ config.txt \ 0.php.bak”;
file_get_contents($ filename); //可能只读“ config.txt”

PHP可以允许通过该字符串,但是基础系统调用(以C为编写)在\0停止,可能导致:

  • 读错误的文件
  • 绕过文件扩展名(文件上传中的安全风险)

解决方案:始终对输入进行消毒和验证:

 if(strpos($ filename,“ \ 0”)!== false){
    抛出新的无效Exception(“在文件名中不允许null字节”);
}

更好的是,使用白名单进行文件操作,并在可能的情况下避免动态文件名。


陷阱2:文件上传中的安全风险

攻击者可以将null字节注入$_GET$_POST或上传文件名以利用字符串终止行为。

危险模式的例子:

 //不要这样做
$ uploadDir ='/uploads/';
move_uploaded_file($ _ files ['file'] ['tmp_name'],$ uploadDir。$ _post ['filename']);

如果$_POST['filename']"shell.php\0.jpg" ,则某些系统可能将其保存为shell.php (因为\0之后忽略.jpg ),绕过扩展检查。

解决方案

  • 永远不要相信用户输入文件路径
  • 使用basename()剥离目录信息
  • 验证实际文件内容上的扩展名,而不仅仅是名称
  • 明确过滤null字节:
     if(preg_match('/[\ x00]/',$ filename)){
      die(“无效文件名”);
    }

陷阱3: strcmp和字符串比较的问题

虽然PHP的本机字符串比较( =====strcmp )正确处理null字节,但使用依赖C字符串的扩展程序或数据库驱动程序时可能会出现问题。

例如,比较php中的"admin\0""admin"

 var_dump(“ admin \ 0” ===“ admin”); // 错误的
var_dump(strcmp(“ admin \ 0”,“ admin”)); //非零(不相等)

这在纯PHP中是安全的,但是如果这些字符串通过基于C的驱动器在SQL查询中使用,则可能会发生截断。

最佳实践:使用准备好的语句避免注入并确保数据完整性:

 $ stmt = $ pdo->准备(“从用户select * select * username =?”);
$ stmt->执行([$ username]); // PDO处理逃逸和二进制数据

陷阱4:正式表达式的不当行为

PHP中的PCRE功能通常是二进制安全的,但是NULL字节仍然会引起混乱,尤其是在处理用户输入时。

例子:

 preg_match('/^[\ w \。] $/',“ file.txt \ 0.php”); //可能返回1(!)

正则表达式与空字节匹配,但完整的字符串不安全。

修复:明确拒绝null字节,然后再发行:

 if(strpos($输入,“ \ 0”)!== false){
    //拒绝或处理
}

或使用\A\z (绝对启动/结束)使用更严格的模式:

 preg_match('/\ a [\ w \。] \ z/',$ input); //确保完整的弦匹配

一般最佳实践

为了避免php中的零字节陷阱:

  • ✅从用户输入中的过滤null字节
     $ clean = str_replace(“ \ 0”,'',$ input); //或完全拒绝
  • ✅使用basename()realpath()filter_input()之类的内置功能()
  • 验证和消毒所有外部数据 - 永远不要假设它是安全的
  • 避免在系统调用或SQL中直接插值
  • ✅处理原始数据时,请使用二进制安全功能

  • 零字节并不是固有的邪恶,但是它们通过PHP的高级字符串处理与C的低级世界之间的差距。

    基本上:将null字节视为其他任何危险输入,将其滤出或明确处理。

    以上是用零字节和PHP中的字符串终止解决常见的陷阱的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

Rimworld Odyssey如何钓鱼
1 个月前 By Jack chen
Kimi K2:最强大的开源代理模型
1 个月前 By Jack chen
我可以有两个支付帐户吗?
1 个月前 By 下次还敢

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Laravel 教程
1602
29
PHP教程
1506
276
用零字节和PHP中的字符串终止解决常见的陷阱 用零字节和PHP中的字符串终止解决常见的陷阱 Jul 28, 2025 am 04:42 AM

nullbytes(\ 0)cancauseunexpectedBehaviorInphpWhenInterfacingWithCextensOsSySycallsBecaUsectReats \ 0asastringTermInator,EventHoughPhpStringSareBinary-SaftringsareBinary-SafeanDeandSafeanDeandPresserve.2.infileperations.2.infileperations,filenamecontakecontakecontablescontakecontabternallikebybybytartslikeplikebybytrikeplinebybytrikeplike'''''''';

带有' sprintf”和' vsprintf”的高级字符串格式化技术 带有' sprintf”和' vsprintf”的高级字符串格式化技术 Jul 27, 2025 am 04:29 AM

sprintf和vsprintf在PHP中提供高级字符串格式化功能,答案依次为:1.可通过%.2f控制浮点数精度、%d确保整数类型,并用d实现零填充;2.使用%1$s、%2$d等positional占位符可固定变量位置,便于国际化;3.通过%-10s实现左对齐、]右对齐,适用于表格或日志输出;4.vsprintf支持数组传参,便于动态生成SQL或消息模板;5.虽无原生命名占位符,但可通过正则回调函数模拟{name}语法,或结合extract()使用关联数组;6.应通过substr_co

防御弦处理:防止XSS和PHP注射攻击 防御弦处理:防止XSS和PHP注射攻击 Jul 25, 2025 pm 06:03 PM

TodefendagainstXSSandinjectioninPHP:1.Alwaysescapeoutputusinghtmlspecialchars()forHTML,json_encode()forJavaScript,andurlencode()forURLs,dependingoncontext.2.Validateandsanitizeinputearlyusingfilter_var()withappropriatefilters,applywhitelistvalidation

导航PHP字符串编码的迷宫:UTF-8及以后 导航PHP字符串编码的迷宫:UTF-8及以后 Jul 26, 2025 am 09:44 AM

UTF-8处理在PHP中需手动管理,因PHP默认不支持Unicode;1.使用mbstring扩展提供多字节安全函数如mb_strlen、mb_substr并显式指定UTF-8编码;2.确保数据库连接使用utf8mb4字符集;3.通过HTTP头和HTML元标签声明UTF-8;4.文件读写时验证并转换编码;5.JSON处理前确保数据为UTF-8;6.利用mb_detect_encoding和iconv进行编码检测与转换;7.预防数据损坏优于事后修复,需在所有层级强制使用UTF-8以避免乱码问题。

与PHP的PCRE功能相匹配的高级模式 与PHP的PCRE功能相匹配的高级模式 Jul 28, 2025 am 04:41 AM

PHP的PCRE函数支持高级正则功能,1.使用捕获组()和非捕获组(?:)分离匹配内容并提升性能;2.利用正/负向先行断言(?=)和(?!))及后发断言(?

超越JSON:了解PHP的本地字符串序列化 超越JSON:了解PHP的本地字符串序列化 Jul 25, 2025 pm 05:58 PM

PHP的原生序列化比JSON更适合PHP内部数据存储与传输,1.因为它能保留完整数据类型(如int、float、bool等);2.支持私有和受保护的对象属性;3.可安全处理递归引用;4.反序列化时无需手动类型转换;5.在性能上通常优于JSON;但不应在跨语言场景使用,且绝不能对不可信输入调用unserialize(),以免引发远程代码执行攻击,推荐在仅限PHP环境且需高保真数据时使用。

字符串作为价值对象:一种现代的特定领域字符串类型的方法 字符串作为价值对象:一种现代的特定领域字符串类型的方法 Aug 01, 2025 am 07:48 AM

Rawstringsindomain-drivenapplicationsshouldbereplacedwithvalueobjectstopreventbugsandimprovetypesafety;1.Usingrawstringsleadstoprimitiveobsession,whereinterchangeablestringtypescancausesubtlebugslikeargumentswapping;2.ValueobjectssuchasEmailAddressen

解开二进制数据:PHP的' PACK()”和' unvack()”的实用指南````'' 解开二进制数据:PHP的' PACK()”和' unvack()”的实用指南````'' Jul 25, 2025 pm 05:59 PM

PHP的pack()和unpack()函数用于在PHP变量与二进制数据之间转换。1.pack()将变量如整数、字符串打包成二进制数据,unpack()则将二进制数据解包为PHP变量,二者均依赖格式字符串指定转换规则。2.常见格式码包括C/c(8位有/无符号字符)、S/s(16位短整型)、L/l/V/N(32位长整型,分别对应不同字节序)、f/d(浮点/双精度)、a/A(填充字符串)、x(空字节)等。3.字节序至关重要:V表示小端序(Intel),N表示大端序(网络标准),跨平台通信时应优先使用V

See all articles