php常见安全问题实例讲解( 二 )
另外设置 Cookie 时,如果无需 JS 读取的话,请必须设置为 "HTTP ONLY" 。这个设置可以令 JavaScript 无法读取 PHP 端种的 Cookie 。
3. XSRF/CSRF
CSRF 是跨站请求伪造的缩写,它是攻击者通过一些技术手段欺骗用户去访问曾经认证过的网站并运行一些操作 。
虽然此处展示的例子是 GET 请求,但只是相较于 POST 更容易理解,并非防护手段,两者都不是私密的 Cookies 或者多步表单 。
假如你有一个允许用户删除账户的页面,如下所示:
<?php
//delete-account.php
$confirm = $_GET['confirm'];
if($confirm === 'yes') {
//goodbye
}
攻击者可以在他的站点上构建一个触发这个 URL 的表单(同样适用于 POST 的表单),或者将 URL 加载为图片诱惑用户点击:
<img src=https://www.isolves.com/it/cxkf/yy/php/2019-07-10/"https://example.com/delete-account.php?confirm=yes" />
用户一旦触发,就会执行删除账户的指令,眨眼你的账户就消失了 。
防御这样的攻击比防御 XSS 与 SQL 注入更复杂一些 。
最常用的防御方法是生成一个 CSRF 令牌加密安全字符串,一般称其为 Token,并将 Token 存储于 Cookie 或者 Session 中 。
每次你在网页构造表单时,将 Token 令牌放在表单中的隐藏字段,表单请求服务器以后会根据用户的 Cookie 或者 Session 里的 Token 令牌比对,校验成功才给予通过 。
由于攻击者无法知道 Token 令牌的内容(每个表单的 Token 令牌都是随机的),因此无法冒充用户 。
<?php /* 你嵌入表单的页面 */ ?>
<form action="/delete-account.php" method="post">
<input type="hidden" name="csrf" value=https://www.isolves.com/it/cxkf/yy/php/2019-07-10/"">
<input type="hidden" name="confirm" value=https://www.isolves.com/it/cxkf/yy/php/2019-07-10/"yes" />
<input type="submit" value=https://www.isolves.com/it/cxkf/yy/php/2019-07-10/"Delete my account" />
</form>
##
<?php
//delete-account.php
$confirm = $_POST['confirm'];
$csrf = $_POST['csrf'];
$knownGoodToken = $_SESSION['csrf'];
if($csrf !== $knownGoodToken) {
die('Invalid request');
}
if($confirm === 'yes') {
//goodbye
}
请注意,这是个非常简单的示例,你可以加入更多的代码 。如果你使用的是像 Symfony 这样的 PHP 框架,那么自带了 CSRF 令牌的功能 。
4. LFI
LFI (本地文件包含) 是一个用户未经验证从磁盘读取文件的漏洞 。
我经常遇到编程不规范的路由代码示例,它们不验证过滤用户的输入 。我们用以下文件为例,将它要渲染的模板文件用 GET 请求加载 。
<body>
<?php
$page = $_GET['page'];
if(!$page) {
$page = 'main.php';
}
include($page);
?>
</body>
由于 Include 可以加载任何文件,不仅仅是 PHP,攻击者可以将系统上的任何文件作为包含目标传递 。
index.php?page=../../etc/passwd
这将导致 /etc/passwd 文件被读取并展示在浏览器上 。
要防御此类攻击,你必须仔细考虑允许用户输入的类型,并删除可能有害的字符,如输入字符中的 “.” “/” “” 。
如果你真的想使用像这样的路由系统(我不建议以任何方式),你可以自动附加 PHP 扩展,删除任何非 [a-zA-Z0-9-_] 的字符,并指定从专用的模板文件夹中加载,以免被包含任何非模板文件 。
我在不同的开发文档中,多次看到造成此类漏洞的 PHP 代码 。从一开始就要有清晰的设计思路,允许所需要包含的文件类型,并删除掉多余的内容 。你还可以构造要读取文件的绝对路径,并验证文件是否存在来作为保护,而不是任何位置都给予读取 。
5. 不充分的密码哈希
大部分的 Web 应用需要保存用户的认证信息 。如果密码哈希做的足够好,在你的网站被攻破时,即可保护用户的密码不被非法读取 。
首先,最不应该做的事情,就是把用户密码明文储存起来 。大部分的用户会在多个网站上使用同一个密码,这是不可改变的事实 。当你的网站被攻破,意味着用户的其他网站的账号也被攻破了 。
其次,你不应该使用简单的哈希算法,事实上所有没有专门为密码哈希优化的算法都不应使用 。哈希算法如 MD5 或者 SHA 设计初衷就是执行起来非常快 。这不是你需要的,密码哈希的终极目标就是让黑客花费无穷尽的时间和精力都无法破解出来密码 。
推荐阅读
- PHP变量及实例
- 共有产权常见的10个问题
- 做抖音种草视频应该拍什么风格的视频?抖音常见的视频类型。
- 华为云7项安全服务入选中国网络安全行业全景图
- 8个穴位治8种常见病,保你一辈子健康
- 苹果|性能、拍照、安全全都要 商务精英选这三款手机准没错
- 腾讯安全:新型挖矿木马借提权工具攻击 超500台服务器中招
- 红酒为什么需要醒酒?其实是为了你的安全
- 太极拳有哪些常见功效
- Windows 常见的进程列表