mysql动物书_PHP动物书总结09-13

9.图像 10.PDF 11.XML

这三章用到的时候再看

12.安全

1.过滤输入

所有非程序生成的数据都可能是恶意的,都需要过滤

过滤时要判断输入数据大小长度是否合适,是否在规定的有效数据集当中

先使用静态条件过滤,再使用数据库过滤

示例:

//颜色值必须在规定的颜色集当中

if (!in_array($color, $color_set)) {return false;

}//中文名长度必须在3到10之间

$len = mb_strlen($cn_name);if ($len >= 10 || $len <= 3) {return false;

}//英文名只允许字母、空格、单引号、连字符

if (!preg_match(‘/[^A-Za-z \‘\-]/‘), $en_name) {return false;

}

2.跨站脚本攻击XSS

XSS是最常见的网页程序安全漏洞,它允许恶意web用户将恶意代码植入到提供给其它用户的页面中,恶意代码可以在其它页面上执行窃取信息等操作。

为了预防XSS,需要从输出中转义上下文:

$html = array(‘username‘ => htmlentities($_POST[‘username‘], ENT_QUOTES, ‘UTF-8‘),);echo $html[‘username‘];

应该过滤输入来提供冗余保护,但不能依赖过滤,因为它不是问题的根源(根源在输出,所以输出要转义才行)。

关于html实体:http://www.w3school.com.cn/html/html_entities.asp

有些符号想要显示在页面上,比如

3.SQL注入

(1)示例:

$username = $_POST[‘username‘];$hash = hash($_POST[‘password‘]);$sql = "SELECT count(*) FROM users WHERE username = ‘{$username}‘ and password = ‘{$hash}‘ ";

这里的问题是没有转义用户名,它的值可以篡改SQL查询的格式,鉴于此漏洞很常见,很多攻击者会使用如下用户名:

chris‘ --

这样就可以不用密码就可以用chris访问账户

篡改后的SQL查询是:

SELECT count(*) FROM users WHERE username = ‘chris‘ --‘ AND password = ‘xxx

两个破折号(--)表示sql注释,这个查询等同于:

SELECT * FROM users WHERE username = ‘chris‘

(2)SQL注入出问题的是plain sql,使用参数绑定param bind sql可以很好解决这个问题

bind param sql防SQL注入原理:数据库服务器会把完整参数当做sql语句的参数来执行sql语句,参数的任何部分都不会被执行,这样就不会出现SQL注入的问题了

所以,所有根据用户输入数据进行sql查询的地方理论上都应该使用param bind sql

(3)防止针对plain sql的SQL注入,可以在拼接参数之前对参数过滤和转义。示例如下:

if (preg_match(...), $username) {return false;

}$username = mysql_real_escape_string($username);

实际上,为了安全-不只是防止SQL注入的目的,所有用户输入数据都应该过滤

4.文件名攻击

可以通过传入特殊的文件名进行攻击

(1)使用相对路径访问特殊文件

比如想要访问用户资料文件,文件放在/usr/local/目录下,以用户名作文件名,例如:

include("/usr/local/{$username}");

如果传入的$username值为../../etc/passwd作为用户名,就可能输出/etc/passwd的内容

(2)使用远程文件

默认情况下,php可以用打开本地文件的函数打开远程文件,fopen、include、require等函数可以通过传递URL做文件名打开远程文件,例如:

chdir(‘/usr/local/‘);$fp = fopen($username, ‘r‘);

如果$username的值为http://www.example.com/myfile,打开的就是一个远程文件,而不是本地的

如果允许用户告诉你要include哪个文件,情况会更糟糕,例如:

$file = $_REQUEST[‘theme‘];include($file);

如果用户传递了http://www.example.com/badcode.inc作为theme字段的值,并且variables_order配置包括GET或POST,php脚本将会加载远程代码执行

有多种方法可以检查文件名限制此类攻击:禁用远程文件访问、用realpath和basename检查真正的文件名是否和传入参数一致、配置open_basedir选项限制超出网站目录的文件系统访问

例子:

$filename = $_POST[‘username‘];$vetted = basename(realpath($filename));if ($filename !== $vetted) {die("{$filename} is not a good username.");

}include("/usr/local/{$filename}");

5.会话攻击

攻击者嵌入会话标识符的链接:

Log In

受害者单击了链接以会话标识符1234继续访问,如果受害人进行了登录,攻击者可以劫持受害者的会话来提升权限

还有一些这种攻击的变体,比如用cookie达到同样的目的

防护很简单,当权限等级改变时,比如用户登录,用session_generate_id()重新生成会话标识符:

if (check_auth($_POST[‘username‘], $_POST[‘password‘])) {$_SESSION[‘auth‘] = TRUE;

session_regerate_id(TRUE);

}

6.文件上传攻击

(1)不要相信浏览器提供的文件名

浏览器可能会提供诸如/etc/passwd、/home/ramus/.forward的文件名

可以在与用户交互中使用浏览器提供的名字,但是要自己生成唯一的名字用作实际调用的文件

例子:

$browserName = $_FILES[‘image‘][‘name‘];$tempName = $_FILES[‘image‘][‘tmp_name‘];echo "Thanks for sending me {$browserName}";$counter++;$filename = "image_{$counter}";if (is_uploaded_file[$tempName]) { //使用is_uploaded_file确保是上传的文件

move_upload_file($tempName, "/web/images/{$filename}");

}else{die("There was a problem processing the file.");

}

(2)堤防文件系统填充

攻击者可能会上传很大的文件制造拒绝服务攻击

在php.ini中post_max_size选项设置请求最大尺寸,同时需要在相应的Apache/Nginx设置文件尺寸

(3)限制访问特定目录

php.ini中的open_basedir选项可以限制php只能操作该目录和它的子目录

(4)尽量不使用文件,而使用数据库

由于一个机器上php脚本都使用同一用户(www/nobody)运行,所以不同用户的文件、同一机器上不同网站的文件能被其它用户或网站访问到,比如存储在/tmp/sess_id的用户会话文件就可能被其它用户篡改或添加

(5)隐藏PHP代码库

如果网站根目录时/home/httpd/html,所有该目录下的文件都可以通过URL下载到,代码库、配置文件、日志文件和其它数据应该放在该目录外面,比如放进/home/httpd/myapp。同时应该在Web服务器配置,不可以下载.php等文件。

7.特殊函数

eval、exec、system等执行脚本的函数要谨慎使用,因为很容易被攻击者利用,如果用不到的话应该在php.ini禁用掉

13.应用技术

(1)代码库

利用常用的代码构建代码库,把涉及到的函数放到一个php文件里。例如一个辅助创建HTML表单元素的库文件:其中一个函数创建textarea,一个函数创建设置日期时间的弹出表单

(2)模板系统

模板系统分离php代码和页面布局,使设计者专注于页面设计,程序员专注于数据逻辑。模板系统最基本的思想是网页包含可被动态内容替换的特殊标记。

Smarty是一个高效的模板系统(需要研究下)

(3)输出缓冲

默认php使用echo或类似的命令在每个命令执行完后将结果发送到浏览器,可以用php的输出缓冲函数来收集想要发送到浏览器的数据,这样可以获取内容长度、调整内容、批量延迟输出、清空内容、压缩内容等。

ob_start([callback]) //callback是后处理函数,缓冲区刷新(flush)后会向函数传递收集到的输出,并且返回一个将要发送到浏览器的字符串。

ps:输出缓冲用来拦截输出,也包括var_dump等内置函数的输出

(4)错误报告

正常的,当php脚本发生错误时,错误信息会被插入到脚本的输出中,如果错误时致命的,脚本将会停止执行

有三种错误等级:提示notice、警告warning、错误error,error包括解析错误parse error,除了parse error外都是运行时错误

默认,除了notice都会捕获并且展示给用户,但可以在php.ini中使用error_reporting选项指定输出级别,或在脚本中使用error_reporting()函数来指定

所有错误error:E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR

除notice外的所有错误:E_ALL & ~E_NOTICE

使用@符号可以禁止语句输出错误信息(只能抑制输出错误信息,不能抑制错误造成的结果,致命错误仍然会导致程序停止运行)

(5)错误处理和记录

可以使用set_error_handler()函数注册错误处理器,当错误发生时,错误处理器会被触发。同时可以使用error_log()函数,把错误记录到管理员放置日志的地方。

例子:

//日志分流错误处理器

function log_roller($error, $errorString) {$file = ‘/var/log/php_errors.log‘;if (filesize($filesize) > 1024) { //保证日志不会大于1k

rename($file, $file . (string)time());clearstatcache();

}error_log($errorString, 3, $file);

}set_error_handler(‘log_roller‘);for ($i = 0; $i < 5000; $i++) {trigger_error(time() . ‘:Just an error\n‘);

}

php.ini中配置不显示错误,而是把错误输出到日志文件中

display_errors=off

log_errors=on

error_log=/tmp/errors.log

(6)性能调优

开始不要太关注优化,先让代码工作起来,然后找到慢的部分去优化。

优化代码的目标是缩短代码运行时间和内存占用,优化的代码可读性可能会差一些。

基准测试benchmark

可以用Apache基准测试工具ab来做性能测试

./ab -c 10 -n 1000 http://localhost/info.php//10个并发请求执行1000次

查看代码运行时间

$start = microtime();phpinfo();$end = microtime();echo $end - $start; //执行时间

问题:tcp rpc相对于http rpc的优点是什么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值