作者:Thomas Myer 来源:IBM DeveloperWorks 2007-02-27 最后更新:2007-02-27 13:10:55
缓冲区溢出攻击
缓冲区溢出攻击 试图使 PHP 应用程序中(或者更精确地说,在 Apache 或底层操作系统中)的内存分配缓冲区发生溢出。请记住,您可能是使用 PHP 这样的高级语言来编写 Web 应用程序,但是最终还是要调用 C(在 Apache 的情况下)。与大多数低级语言一样,C 对于内存分配有严格的规则。
缓冲区溢出攻击向缓冲区发送大量数据,使部分数据溢出到相邻的内存缓冲区,从而破坏缓冲区或者重写逻辑。这样就能够造成拒绝服务、破坏数据或者在远程服务器上执行恶意代码。
防止缓冲区溢出攻击的惟一方法是检查所有用户输入的长度。例如,如果有一个表单元素要求输入用户的名字,那么在这个域上添加值为 40 的 maxlength 属性,并在后端使用 substr() 进行检查。清单 13 给出表单和 PHP 代码的简短示例。
清单 13. 检查用户输入的长度
<?php
if ($_POST['submit'] == "go"){
$name = substr($_POST['name'],0,40);
//continue processing....
}
?>
<form action="<?php echo \
$_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name=\
"name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form>
为什么既提供 maxlength 属性,又在后端进行 substr() 检查?因为纵深防御总是好的。浏览器防止用户输入 PHP 或 MySQL 不能安全地处理的超长字符串(想像一下有人试图输入长达 1,000 个字符的名称),而后端 PHP 检查会确保没有人远程地或者在浏览器中操纵表单数据。
正如您看到的,这种方式与前一节中使用 strlen() 检查 GET 变量 pid 的长度相似。在这个示例中,忽略长度超过 5 位的任何输入值,但是也可以很容易地将值截短到适当的长度,如下所示:
清单 14. 改变输入的 GET 变量的长度
<?php
$pid = $_GET['pid'];
if (strlen($pid)){
if (!ereg("^[0-9]+$",$pid)){
//if non numeric $pid, send them back to home page
}
}else{
//empty $pid, so send them back to the home page
}
//we have a numeric pid, but it may be too long, so let's check
if (strlen($pid)>5){
$pid = substr($pid,0,5);
}
//we create an object of a fictional class Page, which is now
//even more protected from evil user input
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page
//......
//......
?>
注意,缓冲区溢出攻击并不限于长的数字串或字母串。也可能会看到长的十六进制字符串(往往看起来像 \xA3 或 \xFF)。记住,任何缓冲区溢出攻击的目的都是淹没特定的缓冲区,并将恶意代码或指令放到下一个缓冲区中,从而破坏数据或执行恶意代码。对付十六进制缓冲区溢出最简单的方法也是不允许输入超过特定的长度。
如果您处理的是允许在数据库中输入较长条目的表单文本区,那么无法在客户端轻松地限制数据的长度。在数据到达 PHP 之后,可以使用正则表达式清除任何像十六进制的字符串。
清单 15. 防止十六进制字符串
<?php
if ($_POST['submit'] == "go"){
$name = substr($_POST['name'],0,40);
//clean out any potential hexadecimal characters
$name = cleanHex($name);
//continue processing....
}
function cleanHex($input){
$clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form>
您可能会发现这一系列操作有点儿太严格了。毕竟,十六进制串有合法的用途,比如输出外语中的字符。如何部署十六进制 regex 由您自己决定。比较好的策略是,只有在一行中包含过多十六进制串时,或者字符串的字符超过特定数量(比如 128 或 255)时,才删除十六进制串。
跨站点脚本攻击
在跨站点脚本(XSS) 攻击中,往往有一个恶意用户在表单中(或通过其他用户输入方式)输入信息,这些输入将恶意的客户端标记插入过程或数据库中。例如,假设站点上有一个简单的 来客登记簿程序,让访问者能够留下姓名、电子邮件地址和简短的消息。恶意用户可以利用这个机会插入简短消息之外的东西,比如对于其他用户不合适的图片或将 用户重定向到另一个站点的 JavaScript,或者窃取 cookie 信息。
幸运的是,PHP 提供了 strip_tags() 函数,这个函数可以清除任何包围在 HTML 标记中的内容。strip_tags() 函数还允许提供允许标记的列表,比如 <b> 或 <i>。
清单 16 给出一个示例,这个示例是在前一个示例的基础上构建的。
清单 16. 从用户输入中清除 HTML 标记
<?php
if ($_POST['submit'] == "go"){
//strip_tags
$name = strip_tags($_POST['name']);
$name = substr($name,0,40);
//clean out any potential hexadecimal characters
$name = cleanHex($name);
//continue processing....
}
function cleanHex($input){
$clean = preg_replace\
("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
return $clean;
}
?>
<form action=\
"<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type=\
"text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form>
从安全的角度来看,对公共用户输入使用 strip_tags() 是必要的。如果表单在受保护区域(比如内容管理系统)中,而且您相信用户会正确地执行他们的任务(比如为 Web 站点创建 HTML 内容),那么使用 strip_tags() 可能是不必要的,会影响工作效率。
还有一个问题:如果要接受用户输入,比如对贴子的评论或来客登记项,并需要将这个输入向其他用户显示,那么一定要将响应放在 PHP 的 htmlspecialchars() 函数中。这个函数将与符号、< 和 > 符号转换为 HTML 实体。例如,与符号(&)变成 &。这样的话,即使恶意内容躲开了前端 strip_tags() 的处理,也会在后端被 htmlspecialchars() 处理掉。
分享到:
相关推荐
《PHP应用程序安全编程》是Tricia Ballad撰写的一本专著,主要针对PHP开发者,旨在帮助他们理解和实施安全的编程实践。PHP作为一种广泛使用的开源脚本语言,常用于Web开发,但同时也因为其灵活性和易用性,可能导致...
在PHP应用程序开发中,安全是至关重要的一个环节。由于PHP是一种广泛使用的服务器端脚本语言,许多网站和应用程序都是基于PHP构建的。然而,如果不注意安全编程实践,PHP应用可能会遭受各种攻击,如SQL注入、跨站...
本文将深入探讨在PHP应用程序安全编程中所涉及的关键知识点,旨在帮助开发者避免常见安全漏洞,构建更健壮、更安全的系统。 1. **输入验证**:在处理用户输入时,必须对数据进行严格的验证和过滤。这包括URL参数、...
PHP的设计目标是比Perl或C语言编写的CGI程序更安全,但正确配置编译选项和运行时设置以及采用安全编码实践是确保PHP应用程序安全的关键。 在使用PHP开发安全应用的过程中,有几个重要的注意事项: 1. **保持操作...
### PHP应用程序安全编程知识点 #### 一、引言与安全观念 - **目的与受众**:本书面向PHP初学者及具有一定经验的开发者,旨在提升PHP应用程序的安全性。 - **安全误区**:书中强调不应将混淆文件名或目录结构视为...
然而,随着Web安全成为关注焦点,PHP应用程序的安全性问题也日益凸显。许多企业和组织纷纷成立专门的安全团队或聘请安全专家来进行代码审计,以确保其应用程序的安全性。传统的漏洞审计技术已经难以发现新型的安全...
在PHP应用程序安全编程中,确保代码的安全性是至关重要的。PHP是一种广泛使用的开源脚本语言,常用于构建动态网站和Web应用程序。然而,由于其灵活性和动态性,如果不注意安全编程,很容易导致各种安全漏洞,如SQL...
在深入探讨高级PHP应用程序漏洞审核技术...总结,高级PHP应用程序漏洞审核技术不仅涉及代码层面的安全,还涵盖了整体架构、依赖管理和安全意识。通过深入理解这些概念,开发者可以构建更安全、更可靠的PHP应用程序。
确保PHP应用程序的安全性需要从多个层面入手。首先,操作系统应当保持最新状态并安装所有必要的安全补丁。在编译PHP之前,要特别注意以下几点: 1. 整合Apache、PHP和MySQL:通常推荐使用Apache Toolbox来简化这一...
如果多个Web应用程序共用一个应用程序池,则可能存在安全风险,因为一个应用程序的崩溃可能会导致整个应用程序池中的W3wp进程退出,从而影响到其他Web应用程序。因此,如果内存资源允许,通常建议为每个Web应用程序...
### 用PHP构建Android手机应用程序 #### 摘要与关键词解析 本文主要探讨了如何利用PHP语言在Android平台上开发应用程序。通常情况下,Android应用程序主要采用Java或Kotlin进行开发,但通过Android脚本层(SL4A)...
9. **响应式设计**:随着移动设备的普及,响应式设计成为必备技能,确保应用程序在不同设备和屏幕尺寸上都能正常显示。 10. **持续集成/持续部署(CI/CD)**:理解自动化构建和部署流程,如使用Git进行版本控制,...
在PHP的环境中,确保应用程序的安全性至关重要。PHP的旧版本存在一些已知的安全问题,因此推荐使用最新稳定版以减少漏洞的暴露。其中,SQL Injection是PHP应用中常见的安全威胁,它允许攻击者通过注入恶意SQL语句来...
应用程序可能会对Linux系统性能和安全性产生影响,反之亦然。如果影响过大,可能需要重新审视迁移的必要性和方案的正确性。此外,移植过程需考虑操作系统特性对应用程序代码的影响,有时候可能需要通过虚拟化技术来...
揭露 PHP 应用程序中出现的五个常见数据库问题 在 PHP 应用程序中,数据库问题是非常常见的。这篇文章将揭露五个常见的数据库问题,包括数据库模式设计、数据库访问和基于数据库的业务逻辑代码,并提供相应的解决...
4. **测试阶段**:确保网站应用程序的功能正确性、性能和安全性。常用的测试方法包括单元测试、集成测试、性能测试和安全测试等。 5. **部署上线**:将开发完成的网站应用程序部署到生产环境,并进行必要的监控和...
测试阶段确保应用程序的性能、稳定性和安全性。这包括单元测试、集成测试、系统测试和用户体验测试。此外,还需进行兼容性测试,确保应用在不同浏览器和设备上的表现。 5. **发行**: 在测试成功后,准备发布应用...