谈谈关于PHP的代码安全相关的一些致命知识

使用 mysql_real_escape_string() 防止 SQL 注入问题。

使用正则表达式和 strlen() 来确保 GET 数据未被篡改。

使用正则表达式和 strlen() 来确保用户提交的数据不会使内存缓冲区溢出。

使用 strip_tags() 和 htmlspecialchars() 防止用户提交可能有害的 HTML 标记。

避免系统被 Tamper Data 这样的工具突破。

使用惟一的令牌防止用户向服务器远程提交表单。

 

规则1:绝不相信外部数据或者输入数据

比如:GET变量,表单POST,数据库,配置文件,会话变量或者是cookid

解决方法:对用户输入进行清理的简单方法,使用正则表达式来处理,只希望接收字母,字符串限制为特定数量的字符,或者所有的字母都是小写的

$myUsername = cleanInput($_POST[‘username‘]); //clean!
$arrayUsers = array($myUsername, ‘tom’, ‘tommy’); //clean!
define(”GREETING”, ‘hello there’ . $myUsername); //clean!
function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace(”/[^a-z]/”, “”, $clean);
$clean = substr($clean,0,12);
return $clean;
}

规则2:禁用那些使安全性难以实施的PHP设置

例如:要确保禁用register_globals.在项目上线是要确保已经关闭了错误报告级别

规则3:SQL注入

  • 使用mysql_real_escape_string()作为用户输入的包装器。
  • $sql = "select count(*) as ctr from user where username = ‘".mysql_real_escape_string($username)." ‘ and password = ‘".mysql_real_escape_string($pw)." ‘ limit 1 ";

    使用了此函数能对字符串中字符进行转义,使得字符串不能传递‘ 等特殊符号
  • 防止用户操纵变量

在URL地址栏中,通常会有将链接指向template.php?pid = 33或者 template.php?pid = 456 这样的位置,URL中问号后面的部分称之为查询字符串,也称之为GET查询字符串

$pid = $_GET[‘pid‘];

$obj = new Page();

$content = $obj ->fetchPaget($pid);

代码看起来没什么问题,但是用户可以在地址栏上随意输入值了。我们应该确保pid 应该是数字,可以使用 is_numeric(),但还不够,如果是10.2,+0234.34e5,0xff339988f又该如何呢,我们可以使用正则来显示GET变量 preg_match(‘/^[0-9+$]/‘,$pid).还要检查变量的长度是否为0,显示变量的长度,防止缓冲区溢出

$pid = $_GET[‘pid‘];
if (strlen($pid)){
if (!ereg(”^[0-9]+$”,$pid) && strlen($pid) > 5){
}
}else{
}
$obj = new Page;
$content = $obj->fetchPage($pid);

?> [/php]

  • 缓冲区溢出攻击

缓冲区溢出攻击向缓冲区发送大量数据,使部分数据溢出到相邻的内存缓冲区,从而破坏缓冲区或者重写逻辑。这样就能够造成拒绝服务、破坏数据或者在远程服务器上执行恶意代码。
防止缓冲区溢出攻击的惟一方法是检查所有用户输入的长度

if ($_POST[‘submit‘] == “go”){
$name = substr($_POST[‘name‘],0,40);
}
?>

$_SERVER[‘PHP_SELF‘];?>” method=”post”>

Name

“name” id=”name” size=”20″ maxlength=”40″/>

  • 防止十六进制字符

if ($_POST[‘submit‘] == “go”){
$name = substr($_POST[‘name‘],0,40);
$name = cleanHex($name);
}
function cleanHex($input){
$clean = preg_replace(”![\][xX]([A-Fa-f0-9]{1,3})!”, “”,$input);
return $clean;
}

  • 跨站点脚本攻击

PHP 提供了 strip_tags() 函数,这个函数可以清除任何包围在 HTML 标记中的内容。strip_tags() 函数还允许提供允许标记的列表,比如

if ($_POST[‘submit‘] == “go”){

$name = strip_tags($_POST[‘name‘]);

$name = substr($name,0,40);

$name = cleanHex($name);

}

function cleanHex($input){

$clean = preg_replace\

(”![\][xX]([A-Fa-f0-9]{1,3})!”, “”,$input);

return $clean;

}

从安全的角度来看,对公共用户输入使用 strip_tags() 是必要的。如果表单在受保护区域(比如内容管理系统)中,而且您相信用户会正确地执行他们的任务(比如为 Web 站点创建 HTML 内容),那么使用 strip_tags() 可能是不必要的,会影响工作效率。

 

 

  • 远程表单提交

Web 的好处是可以分享信息和服务。坏处也是可以分享信息和服务,因为有些人做事毫无顾忌。

以表单为例。任何人都能够访问一个 Web 站点,并使用浏览器上的 File > Save As 建立表单的本地副本。然后,他可以修改 action 参数来指向一个完全限定的 URL(不指向 formHandler.php,而是指向http://www.yoursite.com/formHandler.php,因为表单在这个站点上),做他希望的任何修改,点击 Submit,服务器会把这个表单数据作为合法通信流接收。

首先可能考虑检查 $_SERVER[‘HTTP_REFERER‘],从而判断请求是否来自自己的服务器,这种方法可以挡住大多数恶意用户,但是挡不住最高明的黑客。这些人足够聪明,能够篡改头部中的引用者信息,使表单的远程副本看起来像是从您的服务器提交的。

处理远程表单提交更好的方式是,根据一个惟一的字符串或时间戳生成一个令牌,并将这个令牌放在会话变量和表单中。提交表单之后,检查两个令牌是否匹配。如果不匹配,就知道有人试图从表单的远程副本发送数据。

要创建随机的令牌,可以使用 PHP 内置的 md5()、uniqid() 和 rand() 函数,如下所示:

清单 18. 防御远程表单提交

[php] session_start();

if ($_POST[‘submit‘] == “go”){

//check token

if ($_POST[‘token‘] == $_SESSION[‘token‘]){

$name = strip_tags($_POST[‘name‘]);

$name = substr($name,0,40);

$name = cleanHex($name);

}else{

}

}

$token = md5(uniqid(rand(), true));

$_SESSION[‘token‘]= $token;

function cleanHex($input){

$clean = preg_replace(”![\][xX]([A-Fa-f0-9]{1,3})!”, “”,$input);

return $clean;

}

?>

时间: 2024-11-05 02:17:56

谈谈关于PHP的代码安全相关的一些致命知识的相关文章

谈谈js初级封装代码

学js的时候大家肯定或多或少会封装一些函数 举个例子: function my$(id){ return document.getElementById(id) } 当我们调用这个方法的时候,省去了很多很多的代码 don't repeat yourself 这样做的      好处是:使用函数将代码封装,使得复用性更高      弊端是:1.全局变量污染  2.代码结构不够清晰,维护不方便 解决问题就是进步的过程 我们可以这样 var xf = { my$:function(id){ retur

《代码整洁之道》知识整理

第1章 整洁代码 第2章 有意义的命名 要点:名副其实,避免误导,做有意义的区分,使用可搜索的名称 理解:对我来说,命名变得越来越重要.良好的命名可以让程序做自我介绍一般,无需过多的注释,就把握程序脉络.好的命名,也可以让写程序的逻辑变得更清晰. 第3章 函数 要点:函数要短小,每个函数只做一件事,每个函数一个抽象层级,尽量减少函数参数,分隔指令和询问,使用异常替代返回错误码 理解:函数是所有编程语言中的基础,良好的函数编写不仅增加了可读性,对项目扩展也有帮助.在项目中,时常会碰到那种庞然大物的

[00025]-[2015-09-20]-[00]-[代码注入技术 --- 0 基础知识]

[创建线程] HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes; // NULL DWORD dwStackSize, // 0 LPTHREAD_START_ROUTINE lpStartAddress, // .... LPVOID lpParameter, // .... DWORD dwCreationFlags, // 0 LPDWORD lpThreadId // NULL ); HANDLE CreateRe

浅析Java中的构造代码块、静态代码块与构造方法

构造代码块.静态代码块与构造方法是三种不同的代码块,那么他们到底有什么区别呢? 一.简单认识一下构造代码块.静态代码块与构造方法 class A { //构造代码块 { System.out.println("构造代码块A"); } //静态代码块 static { System.out.println("静态代码块A"); } //构造方法 public A() { System.out.println("构造方法A"); } } 二.弄清三者

阅读代码的姿势

作为程序员坚持阅读代码是持续自我提升的有效方法之一.有心的程序员不仅要找到优秀代码阅读,更要注意阅读的方法,从整体架构掌握再逐步深入细节,先“广度优先”,再选自己感兴趣的方面进行“深度历险”. 一般地,在一个程序员的日常工作之中,绝大多数时间都是在「阅读代码」,而不是在「写代码」.但是,阅读代码往往是一件很枯燥的事情,尤其当遇到了一个不漂亮的设计,反抗的心理往往更加强烈. 事实上,变换一下习惯.思路和方法,代码阅读其实是一个很享受的过程.阅读代码的模式,实践和习惯,集大成者莫过于希腊作者Diom

Java程序员看C++代码

从事了几年的android应用开发,这几年一直都是用Java开发,今年找了一家OEM公司,说白了就是Android系统源码定制,在这家公司学习了Python, C++.因为接触JNI会比较多一点,所以下面想和大家谈谈我看C++代码的一些理解. 我主要是从看代码和维护代码的角度来看,不涉及更深的技术层面.也欢迎大家来一起讨论下各自的理解. 首先我个人非常喜欢C++的头文件.C++的头文件类似于Java1.8的接口,可以在这里面定义好所有的接口方法/虚函数, 我觉得好的头文件应该是数据集+行为规范集

面试完 BAT等数十家公司,我想谈谈关于 Android 面试那些事

一. 本文目的 笔者将在本文中就Android开发工程师这一岗位,结合自己最近跳槽的经历,谈一谈自己对于面试的一些看法,希望能帮助到正在跳槽中的你们,也给自己的金三跳槽之旅划个圆满的分号. 注:本文适合工作三年以内的职场菜鸟观看,尤其针对想从小公司到大公司(更准确的说,是从普通公司到优质公司)的情况,大神或骨灰玩家可以关掉了. 二. 背景介绍 2.1 个人经历 抛开背景谈面试和offer是容易误导观众的,所以首先大概说说自己的情况供大家参考,某业内知名211本硕(不提母校名字,不给母校丢脸),计

前端代码异常监控总结

[这个在去年8月就起稿了,一直没有发布....] 一.前言 说到前端监控大家应该都不会陌生,这是现代前端工程的标配之一.引入前端监控系统,可以使用例如fundebug,Sentry等第三方监控神器,当然你完全可以自己定制一套符合实际情况的监控模型.一个监控系统大致可以分为四个阶段:日志采集.日志存储.统计与分析.报告和警告.下面主要从几个方面谈谈我对前端代码异常监控的一些理解. 二.JS异处理 脚本错误一般分为两种:语法错误,运行时错误.常见的处理方式有: 2.1 try..catch 捕获 用

Java生成和解析XML格式文件和字符串的实例代码

1.基础知识:Java解析XML一般有四种方法:DOM.SAX.JDOM.DOM4J. 2.使用介绍1).DOM(1)简介 由W3C(org.w3c.dom)提供的接口,它将整个XML文档读入内存,构建一个DOM树来对各个节点(Node)进行操作.优点就是整个文档都一直在内存中,我们可以随时访问任何节点,并且对树的遍历也是比较熟悉的操作:缺点则是耗内存,并且必须等到所有的文档都读入内存才能进行处理. (2)示例代码: 1.基础知识:Java解析XML一般有四种方法:DOM.SAX.JDOM.DO