Sqlmap: contoh vurneable php code
Examples of vulnerable PHP code? up vote 20 down vote favorite 16
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?
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. php security share|improve this question
asked Nov 23 '09 at 13:29 Mateusz Dymczyk 4,85922258
+1 since it sounds fun :) – Johan Nov 23 '09 at 15:43 add a comment 17 Answers active oldest votes up vote 17 down vote accepted
SQL injection is easy:
$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):
$var = $_POST['var'];
echo "
\n";
allows you to inject Javascript that is run from your site. There are several ways of dealing with this, for example:
$var = strip_tags($_POST['var']);
and
$var = filter_var($_POST['var'], FILTER_SANITIZE_STRING);
share|improve this answer
answered Nov 23 '09 at 13:33 cletus 289k83650810
1
Yep, essentially you can never trust user input, treat it all as malicious input and escape it with addslashes(), strip_tags() or htmlspecialchars() . – Rob Nov 23 '09 at 13:38 14
strip_tags is not sufficient to stop HTML injection (think attribute value injection). Munging the request array with FILTER_SANITIZE_STRING is a terrible hack that should never be used. Instead, avoid HTML injection by calling htmlspecialchars on every string you place into HTML content. – bobince Nov 23 '09 at 13:40 4
you could parse it with a regex... – nickf Nov 23 '09 at 13:42 4
Now that's not fair nickf, you know that sets off the uncontrollable twitching in my left eye. – bobince Nov 23 '09 at 14:01 1
Kaitsuli is right. What if $_POST['var'] is set to UNION SELECT name, password...(you get the idea) FROM users WHERE id=3? – Franz Nov 25 '09 at 20:56 show 5 more comments up vote 14 down vote
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 Location header without rendering any of the output of the script. share|improve this answer
edited Nov 23 '09 at 13:43
answered Nov 23 '09 at 13:36
Ben James
43.2k7115131
Maybe its too early in the morning for me still, but what is the vulnerability here? – Jakub Nov 23 '09 at 13:39 3
The header could be ignored, and the php script is still executing. The private function still executes, even if the user is not logged in. – Ikke Nov 23 '09 at 13:41 1
The header() redirect may not come immediately into effect, or can be deliberately ignored, revealing the private data below. – Pekka 웃 Nov 23 '09 at 13:42 add a comment up vote 11 down vote
Oh boy, you won't be short of examples. Just Google PHP tutorial and every single one of them has enough holes to fill the Albert Hall.
Result 1, w3schools. What's their first example to include user input?
Welcome <?php echo $_POST["fname"]; ?>!
Bzzt. HTML injection, repeated throughout every piece of example code. What's their first database query?
$sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')";
Bzzt. SQL injection, you lose. Next.
Result 2, official PHP tutorial. What's the first example of outputting a variable?
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.
Result 3, tizag.com. What's the first example of echoing user input?
echo "You ordered ". $quantity . " " . $item . ".
";
Bzzt.
Result 4, freewebmasterhelp.com. Too basic to include much, but still manages:
print "Hello $name"; // Welcome to the user
Bzzt.
Result 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? share|improve this answer
answered Nov 23 '09 at 13:58 bobince 283k58378585
"holes to fill the Albert Hall"? Good one. +1 – Franz Nov 25 '09 at 20:57
And you're right. It's quite funny to see example code showing you how to test your code for that and that introducing/missing/leaving out other vulnerability examples... – Franz Nov 25 '09 at 20:59
1
My favourite is the Apress book “Pro PHP Security”. The author does a brief tour of common vulnerabilities and proposes a solution to each (often a quite inappropriate one like mapping POST through an SQL escape). And then in the rest of the examples for solving other vulnerabilities he gets it wrong again, giving code that suffers from the vulnerabilities he just warned us about last chapter. The XSS chapter even has XSS vulnerabilities in its examples of how to avoid slightly-different XSS vulnerabilities. And quite terrifying sections on using eval and system. “Pro” security indeed. – bobince Nov 25 '09 at 21:32 add a comment up vote 9 down vote
Bobby Tables
alt text
Bobby Tables is 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.
It might be someting you want to include in your presentation. share|improve this answer
answered Nov 23 '09 at 13:39 Jon Winstanley 11.7k135091
add a comment up vote 4 down vote
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_globals option. It means you can access your variables like this:
$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=1 to the url, and you're in. share|improve this answer
edited Nov 23 '09 at 13:51
answered Nov 23 '09 at 13:39
nickf
198k107436563
2
The feature this is simulating is register_globals – Ben James Nov 23 '09 at 13:49
ah thanks! it's one of those things I'd blocked from my mind. The horror... the horror... – nickf Nov 23 '09 at 13:50
add a comment
up vote 3 down vote
Another example of a sql-injection-vulnerable login script. This is unfortunately very common among new programmers.
$username = $_POST["username"]; $password = $_POST["password"]; $query = "SELECT username, password
FROM users WHERE (username = '{$username}') AND (password = '{$password}')";
share|improve this answer
answered Nov 23 '09 at 13:36 Jonathan Sampson 129k31290374
5
Not to mention storing passwords in plaintext. – Vilx- Nov 23 '09 at 14:25 add a comment up vote 2 down vote
Today's DailyWTF:
if(strstr($username, '**')) {
$admin = 1; $username = str_replace('**', , $username); $_SESSION['admin'] = 1;
} else {
$admin = 0;
}
share|improve this answer
answered Nov 23 '09 at 14:22
community wiki
Powerlord
just read it on thedailywtf. that code hurts … – knittl Nov 23 '09 at 14:42
...and the one who wroted call himself a programmer?! – Strae Dec 1 '09 at 11:00
add a comment
up vote 2 down vote
Email header injection attacks are a much bigger pain in the neck then you might suspect (unless you've had to deal with them).
This is very bad:
$to = 'contact@domain.com'; $subject = $_POST["subject"]; $message = $_POST["message"]; $headers = "From: ".$_POST["from"]; mail($to,$subject,$message,$headers);
(code copied from the second reference above.) share|improve this answer
answered Nov 23 '09 at 14:27 acrosman 7,82862042
add a comment up vote 2 down vote
CSRF for the win.
<?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 :
<form method="post" action="http://site/updateMyAccount.php">
<input name="email" value="badguy@siteB"/> <input type="submit"/>
</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
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.
Another one is session hijacking. One of the methods to do it is piggybacking. If your server accepts non cookie sessions, you can have URLs like http://siteA/?PHPSESSID=blabla which means your session ID is blabla.
An attacker can start a session and note his session ID, then give the link http://siteA/?PHPSESSID=attackerSessionId to 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.
To mitigate this, you have to use session_regenerate_id when your users credentials change (log in and out, goes in administration section etc.). share|improve this answer
edited Nov 23 '09 at 14:36
answered Nov 23 '09 at 14:18
Arkh
5,9222130
add a comment up vote 2 down vote
HTTP Response Splitting attack
If web application is storing the input from an HTTP request in cookie let's say
<?php setcookie("author",$_GET["authorName"]); ?>
It is very prone to HTTP response splitting attack if input is not validated properly for "\r\n" characters.
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:
HTTP/1.1 200 OK ... Set-cookie: author=AuthorName
HTTP/1.1 200 OK ...
Clearly,the second response is completely controlled by the attacker and can be constructed with any header and body content instead share|improve this answer
edited Nov 23 '09 at 14:57
answered Nov 23 '09 at 14:24
Naga Kiran
3,08542135
Hmm, I think that's PHP version related. PHP 5 seems to encode all special characters into percent encoding. – Tower Nov 24 '09 at 13:09 2
HTTP response splitting has been addressed for quite some time. php.net/releases/5_1_2.php – The Pixel Developer Nov 24 '09 at 17:53 add a comment up vote 1 down vote
Check out the Open Web Application Security Project. They have explanations and examples of lots of different kinds of attacks. http://www.owasp.org/index.php/Category:Attack
share|improve this answer
answered Nov 23 '09 at 13:38 txyoji 3,13311623
add a comment up vote 0 down vote
The WRONG way to do templates.
<?php
include("header.php"); include($_GET["source"]); //http://www.mysite.com/page.php?source=index.php include("footer.php");
?>
share|improve this answer
answered Nov 23 '09 at 13:39 Jonathan Sampson 129k31290374
4
You should also show what's the rigt way to do templates. – Ikke Nov 23 '09 at 13:43
The question was for vulnerable examples, not proper examples. – Jonathan Sampson Nov 23 '09 at 14:51
add a comment
up vote 0 down vote
XSS vulnerabilities are easy to show. Just create a page that puts the value of the GET variable "q" somewhere on the page and then hit the following URL:
This will cause the user's cookies to be displayed in an alert box. share|improve this answer
answered Nov 23 '09 at 13:41 ctford 3,63921741
add a comment up vote 0 down vote
Allowing upload and not checking extension. Observe:
Site A allows image uploading and displays them.
Cracker guy uploads a file and tricks you to believe its an image file (via HTTP mimetypes). This file has PHP extension and contains malicious code. Then he tries to see his image file and because every PHP extesioned file is executed by PHP, the code is run. He can do anything that apache user can do. share|improve this answer
answered Nov 23 '09 at 13:42 Cem Kalyoncu 4,99611239
add a comment up vote 0 down vote
Basic (often security sensitive) operations not working as expected, instead requiring the programmer to use a second "real" version to get non-broken functionality.
The most serious one of these would be where an actual operator is affected: The "==" operator does not work as one would expect, instead the "===" operator is needed to get true equality comparison.
One of the big 3 PHP forum packages was affected by a vulnerability in it's "stay logged in" code. The cookie would contain the user's ID and their password hash. The PHP script would read and cleanse the ID, use it to query the user's correct hash in the database, and then compare it with the one in the cookie to see if they should be automatically logged in.
However the comparison was with ==, so by modifying the cookie, an attacker use a hash "value" of boolean:true, making the hash comparison statement useless. The attacker could thus substitute any user ID to log in without a password. share|improve this answer
answered Nov 23 '09 at 15:30 David 12.5k43671
add a comment up vote 0 down vote
Allowing people to upload files, whether that API is supposed to be used by users or not. For example, if a program uploads some files to a server, and that program will never upload a bad file, that's fine.
But a hacker could trace what is being sent, and where to. He could find out that it is allowing files to be uploaded.
From there, he could easily upload a php file. Once that's done, it's game over. He now has access to all your data and can destroy or change anything he wants.
Another common mistake is allowing flooding. You should put some sane limits on your data. Don't allow users to input nonsensical data. Why is a user's name 2MB in length? Things like that make it so easy for someone flood your database or filesystem and crash the system due to out of space errors. share|improve this answer
answered Nov 23 '09 at 15:38 boytheo 37839
add a comment up vote 0 down vote
There are tons of ways that PHP could be vulnerable. Please see the below two link for Top 10 vulnerabilities with examples and counter-measures.