易受攻击的 PHP 代码示例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1783137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Examples of vulnerable PHP code?
提问by Mateusz Dymczyk
Ok so me and a friend are doing a mini presentation on PHP security (I'm not really into PHP though) and he asked me to find some examples of vulnerable PHP code (one that is prone to SQL injections and all other types of attacks). I was wondering are there any websites with both good and bad pieces of code showing how you should and shouldn't code?
好的,所以我和一个朋友正在做一个关于 PHP 安全性的小型演示(虽然我不是很喜欢 PHP),他让我找到一些易受攻击的 PHP 代码的例子(一个容易受到 SQL 注入和所有其他类型攻击的例子) )。我想知道是否有任何网站都有好的和坏的代码段显示您应该如何编码和不应该如何编码?
Basically I will put them into our website and he will try to hack it, then we will show the "proper" website and he will try to hack it again.
基本上我会将它们放入我们的网站,他会尝试破解它,然后我们将显示“正确”的网站,他将再次尝试破解它。
采纳答案by cletus
SQL injectionis easy:
SQL注入很简单:
$var = $_POST['var'];
mysql_query("SELECT * FROM sometable WHERE id = $var");
This is easily solved by:
这很容易解决:
$var = mysql_real_escape_string($_POST['var']);
The other common one is XSS (cross site scripting):
另一个常见的是XSS(跨站点脚本):
$var = $_POST['var'];
echo "<div>$var</div>\n";
allows you to inject Javascript that is run from your site. There are several ways of dealing with this, for example:
允许您注入从您的站点运行的 Javascript。有几种方法可以解决这个问题,例如:
$var = strip_tags($_POST['var']);
and
和
$var = filter_var($_POST['var'], FILTER_SANITIZE_STRING);
回答by Ben James
A really common beginner's mistake is forget to terminate script execution after a redirect.
一个非常常见的初学者错误是在重定向后忘记终止脚本执行。
<?php
if ($_SESSION['user_logged_in'] !== true) {
header('Location: /login.php');
}
omg_important_private_functionality_here();
The solution:
解决方案:
if ($_SESSION['user_logged_in'] !== true) {
header('Location: /login.php');
exit();
}
This can be missed when testing in a normal browser, because browsers usually follow the Locationheader without rendering any of the output of the script.
在普通浏览器中测试时可能会错过这一点,因为浏览器通常会跟随Location标题而不呈现任何脚本输出。
回答by bobince
Oh boy, you won't be short of examples. Just Google PHP tutorialand every single one of them has enough holes to fill the Albert Hall.
哦,男孩,你不会缺少例子。只是谷歌PHP 教程,每个教程都有足够的漏洞来填补阿尔伯特音乐厅。
Result 1, w3schools. What's their first example to include user input?
结果 1,w3schools。他们第一个包含用户输入的例子是什么?
Welcome <?php echo $_POST["fname"]; ?>!<br />
Bzzt. HTML injection, repeated throughout every piece of example code. What's their first database query?
呸。HTML 注入,在每段示例代码中重复。他们的第一个数据库查询是什么?
$sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')";
Bzzt. SQL injection, you lose. Next.
呸。SQL注入,你输了。下一个。
Result 2, official PHP tutorial. What's the first example of outputting a variable?
结果2,官方PHP教程。输出变量的第一个例子是什么?
echo $_SERVER['HTTP_USER_AGENT'];
Bzzt. HTML injection. Not an easily-exploitable one, but still, bad practice of the sort that is repeated throughout php.net's learning materials.
呸。HTML 注入。不是一个容易利用的方法,但仍然是在 php.net 的学习材料中重复出现的那种糟糕的做法。
Result 3, tizag.com. What's the first example of echoing user input?
结果 3,tizag.com。回显用户输入的第一个示例是什么?
echo "You ordered ". $quantity . " " . $item . ".<br />";
Bzzt.
呸。
Result 4, freewebmasterhelp.com. Too basic to include much, but still manages:
结果 4,freewebmasterhelp.com。太基础了,无法包含太多内容,但仍然可以管理:
print "Hello $name"; // Welcome to the user
Bzzt.
呸。
Result 5, learnphp-tutorial.com.
结果 5,learnphp-tutorial.com。
<title><?= $greeting ?> World!</title>
Bz...
呜……
I could go on.
我可以继续。
Is it any wonder the general quality of PHP code in the wild is so disastrous, when this woeful rubbish is what coders are learning?
难怪 PHP 代码的总体质量如此糟糕,当编码人员正在学习这种可悲的垃圾时?
回答by Jon Winstanley
Bobby Tables
鲍比桌


Bobby Tablesis a page devoted to detailing the ways that a script can be vulnerable via SQL injection. This is not unique to PHP, however, SQL injection is the cause of many web page vulnerabilities.
Bobby Tables是一个页面,专门详细说明脚本可能通过SQL 注入受到攻击的方式。这不是 PHP 独有的,但是,SQL 注入是导致许多网页漏洞的原因。
It might be someting you want to include in your presentation.
它可能是您想要包含在演示文稿中的内容。
回答by nickf
I've seen code like this written in the past:
我曾经看到过这样写的代码:
foreach ($_REQUEST as $var => $val) {
$$var = $val;
}
It's a way to simulate the maligned register_globalsoption. It means you can access your variables like this:
这是一种模拟恶意register_globals选项的方法。这意味着您可以像这样访问变量:
$myPostedVar
rather than the terribly more complicated:
而不是更复杂的:
$_POST['myPostedVar']
The security risk pops up in situations like this:
在这样的情况下会出现安全风险:
$hasAdminAccess = get_user_access();
foreach ($_REQUEST as $var => $val) {
$$var = $val;
}
if ($hasAdminAccess) { ... }
Since all you'd have to do is add ?hasAdminAccess=1to the url, and you're in.
因为你所要做的就是添加?hasAdminAccess=1到 url,然后你就进入了。
回答by Arkh
CSRF for the win.
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']));
You feel safe with this kind of code. All is good your users can change their emails without injecting SQL because of your code. But, imagine you have this on your site http://siteA/, one of your users is connected. With the same browser, he goes on http://siteB/where some AJAX does the equivalent of this code :
您对这种代码感到安全。一切都很好,您的用户可以更改他们的电子邮件,而无需因为您的代码而注入 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>
Your user just got his email changed without him knowing it. If you don't think this kind of attack is dangerous, ask google about it
您的用户只是在他不知情的情况下更改了他的电子邮件。如果您认为这种攻击不危险,请向 google 询问
To help against this kind of attacks, you can either :
为了帮助抵御这种攻击,您可以:
- Check your user REFERER (far from perfect)
- Implement some tokens you had to your forms and check their presence when getting your data back.
- 检查您的用户 REFERER(远非完美)
- 在表单中实现一些令牌,并在取回数据时检查它们的存在。
Another one is session hiHymaning. One of the methods to do it is piggybacking. If your server accepts non cookie sessions, you can have URLs like http://siteA/?PHPSESSID=blablawhich means your session ID is blabla.
另一种是会话劫持。一种方法是捎带。如果您的服务器接受非 cookie 会话,您可以使用类似http://siteA/?PHPSESSID=blabla 的URL ,这意味着您的会话 ID 是 blabla。
An attacker can start a session and note his session ID, then give the link http://siteA/?PHPSESSID=attackerSessionIdto other users of your website. When these users follow this link, they share the same session as your attacker : a not logged session. So they login. If the website does not do anything, your attacker and your user are still sharing the same session with the same rights. Bad thing if the user is an admin.
攻击者可以启动一个会话并记下他的会话 ID,然后将链接http://siteA/?PHPSESSID=attackerSessionId 提供给您网站的其他用户。当这些用户点击此链接时,他们与攻击者共享相同的会话:未记录的会话。所以他们登录。如果该网站不执行任何操作,则您的攻击者和您的用户仍以相同的权限共享同一个会话。如果用户是管理员,那就不好了。
To mitigate this, you have to use session_regenerate_idwhen your users credentials change (log in and out, goes in administration section etc.).
为了缓解这种情况,当您的用户凭据更改(登录和注销,进入管理部分等)时,您必须使用session_regenerate_id。
回答by Powerlord
if(strstr($username, '**')) {
$admin = 1;
$username = str_replace('**', '', $username);
$_SESSION['admin'] = 1;
} else {
$admin = 0;
}
回答by Naga Kiran
HTTP Response Splitting attack
HTTP 响应拆分攻击
If web application is storing the input from an HTTP request in cookie let's say
如果 Web 应用程序将来自 HTTP 请求的输入存储在 cookie 中,让我们说
<?php setcookie("author",$_GET["authorName"]); ?>
It is very prone to HTTP response splitting attack if input is not validated properly for "\r\n" characters.
如果未正确验证“\r\n”字符的输入,则很容易发生 HTTP 响应拆分攻击。
If an attacker submits a malicious string,such as "AuthorName\r\nHTTP/1.1 200 OK\r\n..",then the HTTP response would be split into two responses of the following form:
如果攻击者提交了一个恶意字符串,例如“AuthorName\r\nHTTP/1.1 200 OK\r\n..”,那么 HTTP 响应将被拆分为以下形式的两个响应:
HTTP/1.1 200 OK
...
Set-cookie: author=AuthorName
HTTP/1.1 200 OK
...
Set-cookie: author=AuthorName
HTTP/1.1 200 OK ...
HTTP/1.1 200 好的...
Clearly,the second response is completely controlled by the attacker and can be constructed with any header and body content instead
显然,第二个响应完全由攻击者控制,可以用任何头部和正文内容来代替
回答by Sampson
Another example of a sql-injection-vulnerable login script. This is unfortunately very common among new programmers.
sql-injection-vulnerable 登录脚本的另一个示例。不幸的是,这在新程序员中很常见。
$username = $_POST["username"];
$password = $_POST["password"];
$query = "SELECT username, password
FROM users
WHERE (username = '{$username}')
AND (password = '{$password}')";
回答by acrosman
Email headerinjection attacksare a much bigger pain in the neck then you might suspect (unless you've had to deal with them).
电子邮件标头注入攻击比您可能怀疑的要大得多(除非您不得不处理它们)。
This is very bad:
这真是太糟了:
$to = '[email protected]';
$subject = $_POST["subject"];
$message = $_POST["message"];
$headers = "From: ".$_POST["from"];
mail($to,$subject,$message,$headers);
(code copied from the second reference above.)
(从上面的第二个参考中复制的代码。)

