好的,所以我和一位朋友正在做一个关于PHP安全性的迷你演示文稿(虽然我不是真正使用PHP),他让我找到一些易受攻击的PHP代码的示例(一个容易出现SQL注入的示例和其他所有代码攻击类型)。我想知道是否有任何网站都有好的和坏的代码片段显示你应该和不应该编码?
基本上我会将它们放入我们的网站,他会尝试破解它,然后我们将展示“适当的”网站,他会再次尝试破解它。
答案 0 :(得分:19)
SQL injection很简单:
$var = $_POST['var'];
mysql_query("SELECT * FROM sometable WHERE id = $var");
这可以通过以下方式轻松解决:
$var = mysql_real_escape_string($_POST['var']);
另一个常见问题是XSS (cross site scripting):
$var = $_POST['var'];
echo "<div>$var</div>\n";
允许您注入从您的网站运行的Javascript。有几种方法可以解决这个问题,例如:
$var = strip_tags($_POST['var']);
和
$var = filter_var($_POST['var'], FILTER_SANITIZE_STRING);
答案 1 :(得分:17)
一个非常常见的初学者错误是忘记在重定向后终止脚本执行。
<?php
if ($_SESSION['user_logged_in'] !== true) {
header('Location: /login.php');
}
omg_important_private_functionality_here();
解决方案:
if ($_SESSION['user_logged_in'] !== true) {
header('Location: /login.php');
exit();
}
在普通浏览器中进行测试时可能会错过这种情况,因为浏览器通常会遵循Location
标头,而不会呈现脚本的任何输出。
答案 2 :(得分:13)
哦,孩子,你不会缺少例子。只是谷歌PHP tutorial,其中每一个都有足够的空洞来填补阿尔伯特音乐厅。
结果1,w3schools。他们第一个包含用户输入的例子是什么?
Welcome <?php echo $_POST["fname"]; ?>!<br />
Bzzt。 HTML注入,在每个示例代码中重复。他们的第一个数据库查询是什么?
$sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')";
Bzzt。 SQL注入,你输了。下一步。
结果2,官方PHP教程。输出变量的第一个例子是什么?
echo $_SERVER['HTTP_USER_AGENT'];
Bzzt。 HTML注入。不是一个容易被利用的,但仍然是在整个php.net的学习资料中重复的那种不好的做法。
结果3,tizag.com。回应用户输入的第一个例子是什么?
echo "You ordered ". $quantity . " " . $item . ".<br />";
Bzzt。
结果4,freewebmasterhelp.com。太基础了,但仍然管理:
print "Hello $name"; // Welcome to the user
Bzzt。
结果5,learnphp-tutorial.com。
<title><?= $greeting ?> World!</title>
...的Bz
我可以继续。
当编程人员正在学习这个糟糕的垃圾时,难怪野外PHP代码的一般质量是如此灾难性的吗?
答案 3 :(得分:10)
Bobby Tables
Bobby Tables是一个专门用于详细说明脚本可能通过SQL injection容易受到攻击的方式的页面。这不是PHP独有的,但是,SQL注入是许多网页漏洞的原因。
您可能希望在演示文稿中包含这些内容。
答案 4 :(得分:4)
我见过这样的代码:
foreach ($_REQUEST as $var => $val) {
$$var = $val;
}
这是一种模拟受到诽谤的register_globals
选项的方法。这意味着你可以像这样访问你的变量:
$myPostedVar
而不是非常复杂:
$_POST['myPostedVar']
在以下情况下会出现安全风险:
$hasAdminAccess = get_user_access();
foreach ($_REQUEST as $var => $val) {
$$var = $val;
}
if ($hasAdminAccess) { ... }
由于您只需要将?hasAdminAccess=1
添加到网址,然后您就可以了。
答案 5 :(得分:3)
sql-injection-vulnerability登录脚本的另一个例子。不幸的是,这在新程序员中很常见。
$username = $_POST["username"];
$password = $_POST["password"];
$query = "SELECT username, password
FROM users
WHERE (username = '{$username}')
AND (password = '{$password}')";
答案 6 :(得分:3)
if(strstr($username, '**')) {
$admin = 1;
$username = str_replace('**', '', $username);
$_SESSION['admin'] = 1;
} else {
$admin = 0;
}
答案 7 :(得分:3)
HTTP响应拆分攻击
如果Web应用程序在cookie中存储来自HTTP请求的输入,那么就说
<?php setcookie("author",$_GET["authorName"]); ?>
如果未对“\ r \ n”字符正确验证输入,则非常容易发生HTTP响应分裂攻击。
如果攻击者提交恶意字符串,例如“AuthorName \ r \ n \ nNHTTP / 1.1 200 OK \ r \ n ..”,则HTTP响应将分为以下两种形式的响应:
HTTP / 1.1 200 OK
...
Set-cookie:author = AuthorName
HTTP / 1.1 200好的 ...
显然,第二个响应完全由攻击者控制,可以使用任何标题和正文内容构建
答案 8 :(得分:2)
CSRF获胜。
<?php
$newEmail = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$pdoStatement = $pdoDb->prepare('UPDATE user SET email=:email WHERE ID=:id');
$pdoStatement->execute(array(':email'=>$newEmail, ':id'=>$_SESSION['userId']));
这种代码让您感到安全。一切都很好,您的用户可以更改他们的电子邮件,而不会因为您的代码而注入SQL。 但是,假设您在自己的网站http://siteA/上有此内容,则表示您的某个用户已连接。 使用相同的浏览器,他继续http://siteB/,其中一些AJAX与此代码相当:
<form method="post" action="http://site/updateMyAccount.php">
<p>
<input name="email" value="badguy@siteB"/>
<input type="submit"/>
</p>
</form>
您的用户只是在他不知情的情况下更改了电子邮件。如果你不认为这种攻击是危险的,ask google about it
要帮助抵御此类攻击,您可以:
另一个是会话劫持。其中一种方法是搭载。 如果您的服务器接受非cookie会话,您可以使用http://siteA/?PHPSESSID=blabla这样的网址,这意味着您的会话ID是blabla。
攻击者可以开始会话并记下他的会话ID,然后将链接http://siteA/?PHPSESSID=attackerSessionId提供给您网站的其他用户。当这些用户使用此链接时,他们与攻击者共享同一会话:未记录的会话。所以他们登录 如果网站没有执行任何操作,则您的攻击者和您的用户仍然使用相同的权限共享同一会话。如果用户是管理员,那就太糟糕了。
要缓解这种情况,您必须在用户凭据更改时使用session_regenerate_id(登录和注销,进入管理部分等)。
答案 9 :(得分:2)
Email header injection attacks是一个更大的痛苦,你可能会怀疑(除非你不得不处理它们)。
这非常糟糕:
$to = 'contact@domain.com';
$subject = $_POST["subject"];
$message = $_POST["message"];
$headers = "From: ".$_POST["from"];
mail($to,$subject,$message,$headers);
(从上面第二个参考文献复制的代码。)
答案 10 :(得分:1)
查看Open Web Application Security Project。他们有许多不同类型的攻击的解释和例子。 http://www.owasp.org/index.php/Category:Attack
答案 11 :(得分:0)
做模板的错误方法。
<?php
include("header.php");
include($_GET["source"]); //http://www.mysite.com/page.php?source=index.php
include("footer.php");
?>
答案 12 :(得分:0)
XSS漏洞很容易显示出来。只需创建一个页面,将页面上的GET变量“q”的值放在某处,然后点击以下URL:
http://mysite.com/vulnerable_page.php?q%3D%3Cscript%20type%3D%22javascript%22%3Ealert(document.cookie)%3B%3C%2Fscript%3E
这将导致用户的cookie显示在警告框中。
答案 13 :(得分:0)
允许上传而不是检查扩展程序。观察:
网站A允许图片上传并显示它们。
Cracker家伙上传文件并欺骗你相信它的图像文件(通过HTTP mimetypes)。此文件具有PHP扩展名并包含恶意代码。然后他试图查看他的图像文件,因为每个PHP extesioned文件都由PHP执行,代码运行。他可以做任何apache用户可以做的事情。
答案 14 :(得分:0)
基本(通常是安全敏感的)操作无法按预期工作,而是要求程序员使用第二个“真实”版本来获取未破坏的功能。
其中最严重的一个是实际操作符受影响的地方:“==”运算符不能像预期的那样工作,而是需要“===”运算符来获得真正的相等比较。
其中一个3大PHP论坛软件包受到了“保持登录”代码中的漏洞的影响。 cookie将包含用户的ID和密码哈希值。 PHP脚本将读取并清除ID,使用它来查询用户在数据库中的正确哈希值,然后将其与cookie中的哈希值进行比较,以查看它们是否应自动登录。
然而,比较是使用==,因此通过修改cookie,攻击者使用boolean:true的哈希“值”,使得哈希比较语句无用。因此,攻击者可以替换任何用户ID,无需密码即可登录。
答案 15 :(得分:0)
允许用户上传文件,无论该API是否应由用户使用。例如,如果程序将某些文件上传到服务器,并且该程序永远不会上传错误的文件,那就没问题。
但黑客可以追踪发送的内容以及发送到何处。他可以发现它允许上传文件。
从那里,他可以轻松上传一个php文件。一旦完成,它就结束了。他现在可以访问您的所有数据,并可以销毁或更改他想要的任何内容。
另一个常见错误是允许洪水泛滥。你应该对你的数据设置一些理智的限制。不允许用户输入无意义的数据。为什么用户的名字长度为2MB?这样的事情使得有人充斥数据库或文件系统并因空间错误而导致系统崩溃。