Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
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.
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 "<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:
$var = strip_tags($_POST['var']);
and
$var = filter_var($_POST['var'], FILTER_SANITIZE_STRING);
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.
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"]; ?>!<br />
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 . ".<br />";
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?
Bobby Tables
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.
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.
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}')";
Today's DailyWTF:
if(strstr($username, '**')) {
$admin = 1;
$username = str_replace('**', '', $username);
$_SESSION['admin'] = 1;
} else {
$admin = 0;
}
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">
<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
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.).
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
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
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.)
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");
?>
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:
http://mysite.com/vulnerable_page.php?q%3D%3Cscript%20type%3D%22javascript%22%3Ealert(document.cookie)%3B%3C%2Fscript%3E
This will cause the user's cookies to be displayed in an alert box.
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.
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.
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.
Related
i want to make a code generator link,like
www.website.com/register?code=29U3HTR3H219URH923UH419H94RH1298491U2HERUH1?plan_bought=LowReseller
in a functions file on php that is redirecting an user on that link.
$planned = htmlspecialchars($_GET["planbought"]);
// connect to database
$db = mysqli_connect('localhost', 'root', 'pass');
mysqli_select_db($db,"ronp");
function generateRandomString($length = 16)
{
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}
$code_secure = generateRandomString(17); // OR: generateRandomString(24)
$query = "INSERT INTO codes (code, expired, 'date', plan)
VALUES('$code_secure', '0', date, '$planned')";
mysqli_query($db, $query);
header('Location: register?code=', $code_secure);
?>
Process: After payment,paypal will redirect user on https://website.com/functions_generate-ak9esysgenthos.php?planbought=Low
That link will create a code in database,and will redirect user on https://website.com/register?code_secure=(code)
Now the problem is,i get redirected on "https://website.com/register?code=",not "https://website.com/register?code=(the code created in database,like 'J2498JT9UJ249UTJ293UJ59U123J9RU9U')"
If you look at the documentation for header() you'll see that the second parameter is a boolean value. This parameter specifies if the header should be "forcefully" be replaced. You are incorrectly passing your "secure"* code as that parameter.
What you want to do is concatenate the strings instead of passing your "secure" code as a second parameter. What you want to get is
header('Location: register?code=' . $code_secure);
*The "secure" code you are generating is predictable (as you used this code), if you need a secure code you might want to look into openssl_random_pseudo_bytes before PHP 7.0 and random_bytes() in PHP 7.0 or higher, as demonstrated by this answer.
Furthermore, as mentioned by Raymond Nijland your code is vulnerable to SQL injections. See this excellent answer on how you can prevent SQL injections.
Besides the issues mentioned in Tom Udding's answer, there are at least two other issues:
functions_generate-ak9esysgenthos.php can be accessed without any authentication at all. Moreover, it generates a "secure code" blindly, without determining whether a user is logged in or otherwise authorized to access that page (e.g., without determining whether a payment operation is in progress). This could allow anyone with knowledge of the URL to access functions_generate-ak9esysgenthos.php; depending on how your application is implemented, this could cause orders that weren't paid for or even a denial of service attack (due to the additional order codes clogging your database).
You are generating a random "secure code" without checking whether that code was already used. What if /register?code=... finds two records with the same code? Can your application tolerate the risk of generating the same code for different records? (See also my section on unique random identifiers.)
I apologize if this question has been asked before, if it has just link me to it in a comment.
So I've created a web-service for an android/iOS app with php that works like this.
The app sends a request to http://www.example.com/ws/getCookingData.php with 2 $_POST paramaters userID and foodType
The php file then queries the database using those two variables and returns a json_encode result.
My worry is that if someone were to discover my web-service link they could spam it with post requests resulting in 100's of call to my database that are just un-needed
Below is an example of my current getData.php file
<?php
$userID = mysql_escape_string($_POST['userID']);
$foodType = mysql_escape_string($_POST['foodType']);
$mysqli = getDB();
echo json_encode(getDate($mysqli, $userID, $foodType); //mysql database interaction is here
$mysqli->close();
?>
There is nothing here preventing hackers from attempting to post malicious SQL statements into my database
So what I'm wondering is if I added a 3rd parameter to my post request called appID would this be a good solution?
For example if I were to update my getData.php file to below would this be much more secure or is there a vulnerability I'm missing?
<?php
$appID = $_POST['appID'];
if($appID === "hardCodedEquivalentID"){
$userID = mysql_escape_string($_POST['userID']);
$foodType = mysql_escape_string($_POST['foodType']);
$mysqli = getDB();
echo json_encode(getDate($mysqli, $userID, $foodType); //mysql database interaction is here
$mysqli->close();
}
?>
If this is a good solution or there is already an equivalent practice that would achieve what I'm trying to do please let me know
First of all, use mysqli or PDO instead of mysql function which is deprecated. Secondly create a function which will authenticate the user and see whether the user has the permission to access the data. And thirdly try to LIMIT the data to 100 or so if possible.
Hardcoding the appId is not the solution. Create unique Id's for each specific registered user and then match that appId against that particular user. And when their session is expired clear the access token. And at the start of their session, you can login in them and create new access token and can use the same for their entire session.
To answer your first question
My worry is that if someone were to discover my web-service link they
could spam it with post requests resulting in 100's of call to my
database that are just un-needed
If someone wants to DoS you then you can't do much in your code to prevent it but you may try using service like cloudflare. Not worth worrying about it at the beginning.
About
There is nothing here preventing hackers from attempting to post
malicious SQL statements into my database
then just read documentation on PDO
1- Use mysql_real_escape_string()
2- Use str_replace(" ","",$_POST['userID']) and str_replace("%20","",$_POST['userID'])(Because malicious attacks involves in using %20 and space to inject sql query)
3- Add this line to the top of the page, so the script only takes request if its been from your website (That's what I am using too!)
$referrer = $_SERVER['HTTP_REFERER'];
if (strpos($referrer,"yourwebsite.com")) {
} else {
die();
}
I am adding some server-side form validations (using php) in case one of the users of my site has javascript turned off. On one form, there are 10 separate input fields that can be changed. Could someone please tell me which protocol will use less system resources? In the first, I write some mySQL variables to check the user's current settings, and compare these with the posted settings. If all 10 posted values are identical to the current values, don't UPDATE database, else UPDATE the database:
$login_id = $_SESSION['login_id'];
$sql1 = mysql_fetch_assoc(mysql_query("SELECT value1 FROM login WHERE login_id =
'$login_id'"));
$sql1a = $sql1['value1'];
// Eight More, then
$sql10 = mysql_fetch_assoc(mysql_query("SELECT value10 FROM login WHERE login_id =
'$login_id'"));
$sql10a = $sql10['value10'];
$Value1 = $_POST['Value1'];
// Eight More, then
$Value10 = $_POST['Value10'];
//Other validations then the following
if (($sql1a == $Value1)&&($sql2a == $Value2)&&.......($sql10a == $Value10)) {
echo "<script>
alert ('You haven't made any changes to your profile');
location = 'currentpage.php';
</script>";
}
else {
$sqlUpdate = mysql_query("UPDATE login SET value1 = '$Value1',....value10 = '$Value10'
WHERE login_id = '$login_id'");
echo "<script>
alert ('Your profile has been updated!');
location = 'currentpage.php';
</script>";
}//End php
OR is it less expensive to just use the user-posted values (keep the $_POST variables) and avoid checking with the comparison line: (($sql1a == $Value1)&&($sql2a == $Value2)&&.......($sql10a == $Value10)) and just go right to
//Other validations then the following
$sqlUpdate = mysql_query("UPDATE login SET value1 = '$Value1',....value10 = '$Value10'
WHERE login_id = '$login_id'");
echo "<script>
alert ('Your profile has been updated!');
location = 'currentpage.php';
</script>";
Thanks for any input on this!
If I understand correctly, your question is whether it's OK for performance to check the profile for modifications. For me, after I've checked your code, this is about much more than just performance...
Let's start with the performance: AFAIK MySQL queries are slower than basic PHP comparisions, that's true - but on this scale, I really don't think it matters much. We're talking about two very basic queries which won't handle a lot of data.
Let's think about what the end user will see (UX): in the second scenario, the user will not have the most exact feedback telling him/her that no modification has been done. On a profile modification screen, I suppose that might not be intentional, so I would tell that we haven't modified anything. (Also, performing an unnecessary UPDATE query is not the most elegant.)
#aehiilrs is right, please pay attention to that comment. This style of MySQL usage is particularly bad for security - if you keep going with this, you will create a lot of security holes in your PHP code. And those are really easy to discover and exploit, so please, have a good look on the alternatives, starting with PDO as mentioned. Any good PHP book out there will show you the way. You can also have a look at a great Q/A here on StackOverflow: How can I prevent SQL injection in PHP?
I wonder whether it's a good idea to try to update the user interface like you did - I would strongly prefer loading another PHP without any <script> magic in the output. In the result PHP, you can always display something like a CSS-styled statusbar for displaying info like that.
After logging in, I want to redirect users back to the page they were on using PHP. After doing a little searching on the matter and not finding any good solutions, I decided to add a hidden field to the login form which contains the current partial-URL using $_SERVER['REQUEST_URI'].
The server uses this information to redirect the user back to the previous page after logging them in. This has been working correctly, however here is my question.
Overall, what security measures do I need to apply to the url, once it is returned to the server, so that, if tampered with, it will not redirect the user to an external and possibly scrupulous site?
Ex: if I change the value in the form from $_SESSION['REQUEST_URI'] to http://www.google.com, it redirects to Google after login. What is the best way to sanitize this?
*I am currently using mysql_real_escape_string() for SQL injection purposes.
<form action="/signin/" method="post">
<input type="hidden" name="return" value="<?php echo $_SERVER['REQUEST_URI']; ?>" />
</form>
......
$return = mysql_real_escape_string($_POST['return']);
header('Location: '.$return);
As hundreds of other answers/comments have pointed out, everyone should be using mysqli by now. That aside, mysql_real_escape_string() is—as the name implies—for escaping strings that are going to be used in a MySQL query. There is no other use for it. It does not protect you from XSS, as I'll demonstrate...
Setup:
// represent a string without using quotes
function ab($str) {
$out = array();
for ($i = 0; $i < strlen($str); $i++) {
($chr = _ab($str[$i])) || ($chr = 'String.fromCharCode('.ord($str[$i]).')');
}
return implode('+', $out);
}
// represent a character without quotes
function _ab($chr) {
$alpha = array(
'Array', 'Boolean', 'Date', 'Function', 'Iterator', 'Number', 'Object',
'RegExp', 'String', 'ArrayBuffer', 'Float32Array', 'Float64Array', 'JSON',
'Int16Array', 'Int32Array', 'Int8Array', 'Uint16Array', 'Uint32Array',
'Uint8Array', 'Uint8ClampedArray', 'Error', 'EvalError', 'InternalError',
'RangeError', 'ReferenceError', 'StopIteration', 'SyntaxError', 'parseInt',
'TypeError', 'URIError', 'decodeURI', 'decodeURIComponent', 'encodeURI',
'encodeURIComponent', 'eval', 'isFinite', 'isNaN', 'parseFloat', 'uneval'
);
// sort function names by length to minimize output
usort($alpha, function($a, $b){return strlen($a) - strlen($b);});
foreach ($alpha as $fn) {
if (($i = strpos($fn, $chr)) !== false) return "$fn.name[$i]";
}
return false;
}
$mb = chr(0xC2).chr(0x8F); // eats backslashes for breakfast
How it works:
$msg = ab('exploited!');
$payload = "console.log($msg);";
$uri = "$mb\" onmouseover=$payload title=XSS";
// try to sanitize URI
$uri = mysql_real_escape_string($uri);
?>
click me
This generates "URIs" like:
" onmouseover=console.log(Date.name[2]+eval.name[0]+isNaN.name[1]+Date.name[2]); title=hi
which slips right through mysql_real_escape_string() (because the first "character" is actually a partial multibyte character 0xC28F which eats the character immediately after it—the backslash mysql_real_escape_string() inserts to escape the quotation mark), producing:
click me
Which the browser interprets as:
<a title="XSS"" onmouseover="THE_PAYLOAD" href="\">click me</a>
You can test this yourself in Firefox or IE with a console open, and you will see that arbitrary JS code is being executed when you hover over the link, despite the use of mysql_real_escape_string().
mysql_real_escape_string() also doesn't protect you from javascript: links like:
javascript:$.post(%27/account/change-password%27,{newPassword:%27p0wned%27,newPassword2:%27p0wned%27});undefined;
Since percent-encoding isn't used in MySQL, mysql_real_escape_string() doesn't know that %27 is a single-quote or that %22 is a double-quote; so it just ignores them. If the user clicks this link, it'll send a POST request changing their password to one chosen by the attacker. It can be modified to also redirect to the page the user expects to go to, so they'll have no idea of what's just happened.
The only obstacle to this type of attack on your current setup is that URIs are root-relative, so they always start with a "/", but as the first example shows, multibyte strings can be used to trick browsers, and even if the resultant markup is broken, the link will still work due to the leniency of most browsers' HTML parser. This example took me only 15 minutes to come up with after reading your question. A determined attacker could no doubt come up with something that does pose a practical threat.
So to be safe, you have to sanitize your URI using methods specifically designed for HTML and URLs. OWASP's guidelines on URL escaping are a good place to start. Otherwise, the other answers here offer some safer alternatives.
I found this, which looks really good to me: Safely Redirecting with an Open URL Parameter in PHP
He's working with a trusted list of "referers".
Including this, you could work with several ways. Checking the referer, the hidden field in your form and if you're able to, even the server logs.
Except for the server logs, I don't think there's a better way to check where the user came from.
You should store the current url in a session variable like in $_SESSION["last_page_visited"] (except on the login and login submit page). So every time you visit a new page, $_SESSION["last_page_visited"] will be overwritten with the current url. So, no matter which page you visit, the url to last page you visited is saved in the session. And from any page if you click login, after successful login redirect to the url held in that session. And if $_SESSION["last_page_visited"] is empty redirect to index page.
Hope this helps.
If the login page is encrypted with SSL/TLS, and you set the value for the hidden form field from the server (which was verified against your whitelist), then if it gets modified before it's submitted, the user knows about it because they did it.
SSL/TLS is the best practice.
For a while I am more and more confused because of possible XSS attack vulnerabilities on my new page. I've been reading a lot, here on SO and other googled sites. I'd like to secure my page as best as it is possible (yes, i know i cant be secure 100%:).
I also know how xss works, but would like to ask you for pointing out some vulnerable places in my code that might be there.
I use jquery, javascript, mysql, php and html all together. Please let me know how secure it is, when i use such coding. Here's idea.
html:
<input name="test" id="id1" value="abc">
<div id="button"></div>
<div id="dest"></div>
jQuery:
1. $('#id').click (function() {
2. var test='def'
3. var test2=$('#id1').val();
4. $.variable = 1;
5. $.ajax({
6. type: "POST",
7. url: "get_data.php",
8. data: { 'function': 'first', 'name': $('#id').val() },
9. success: function(html){
10. $('#dest').html(html);
11. $('#id1').val = test2;
12. }
13. })
14. })
I guess it's quite easy. I have two divs - one is button, second one is destination for text outputted by "get_data.php". So after clicking my button value of input with id 'id1' goes to get_data.php as POST data and depending on value of this value mysql returns some data. This data is sent as html to 'destination' div.
get_data.php should look like this:
[connecting to database]
switch($_POST['function']) {
case 'first':
3. $sql_query = "SELECT data from table_data WHERE name = '$_POST[name]'";
break;
default:
$sql_query = "SELECT data from table_data WHERE name = 'zzz'";
}
$sql_query = mysql_query($sql_query) or die(mysql_error());
$row = mysql_fetch_array($sql_query);
echo $row['data']
For now consider that data from mysql is free from any injections (i mean mysql_real_escaped).
Ok, here are the questions:
JQuery part:
Line 2: Can anybody change the value set like this ie. injection?
Line 3 and 11: It's clear that putting same value to as was typed before submiting is extremely XSS threat. How to make it secure without losing functionality (no html tags are intended to be copied to input)
Line 4: Can anybody change this value by injection (or any other way?)
Line 8: Can anybody change value of 'function' variable sent via POST? If so, how to prevent it?
Line 10: if POST data is escaped before putting it into database can return value (i mean echoed result of sql query) in some way changed between generating it via php script and using it in jquery?
PHP part:
Please look at third line. Is writing: '$_POST[name]' secure? I met advice to make something like this:
$sql_query = "SELECT data from table_data WHERE name = " . $_POST['name'];
instead of:
$sql_query = "SELECT data from table_data WHERE name = '$_POST[name]'";
Does it differ in some way, especially in case of security?
Next question to the same line: if i want to mysql_real_escape() $_POST['name'] what would be the best solution (consider large array of POST data, not only one element like in this example):
- to mysql_real_escape() each POST data in each query like this:
$sql_query = "SELECT data from table_data WHERE name = " . mysql_real_escape($_POST['name']);
to escape whole query before executing it
$sql_query = "SELECT data from table_data WHERE name = " . $_POST['name'];
$sql_query = mysql_real_escape($sql_query);
to write function that iterates all POST data and escapes it:
function my_function() {
foreach ( $_POST as $i => $post ) {
$_POST[$i] = mysql_real_escape($post)
}
}
What - in your opinion is best and most secure idea?
This post became quite large but xss really takes my sleep away :) Hope to get help here dudes once again :) Everything i wrote here was written, not copied so it might have some small errors, lost commas and so on so dont worry about this.
EDIT
All right so.. if I understand correctly filtering data is not necessery at level of javascript or at client side at all. Everything should be done via php.
So i have some data that goes to ajax and further to php and as a result i get some another kind of data which is outputted to the screen. I am filtering data in php, but not all data goes to mysql - part od this may be in some way changed and echoed to the screen and returned as 'html' return value of successfully called ajax. I also have to mention that I do not feel comfortable in OOP and prefering structural way. I could use PDO but still (correct me if i am wrong) i have to add filtering manually to each POST data. Ofcourse i get some speed advantages. But escaping data using mysql_real_escape looks to me for now "manual in the same level". Correct me if i am wrong. Maybe mysql_realescape is not as secure as PDO is - if so that's the reason to use it.
Also i have to mention that data that doesnt go to database has to be stripped for all malicious texts. Please advice what kind of function I should use because i find a lot of posts about this. they say "use htmlentities()" or "use htmlspecialchars()" and so on.
Consider that situation:
Ajax is called with POST attribute and calls file.php. It sends to file.php POST data i.e. $_POST['data'] = 'malicious alert()'. First thing in file.php I should do is to strip all threat parts from $_POST['data']. What do you suggest and how do you suggest I should do it. Please write an example.
XSS is Cross-site scripting. You talk about SQL injection. I will refer to the latter.
JQuery Part
It's possible to change every single JavaScript command. You can try it yourself, just install Firebug, change the source code or inject some new JavaScript code into the loaded page and do the POST request. Or, use tools like RestClient to directly send any POST request you like.
Key insight: You cannot control the client-side. You have to expect the worst and do all the validation and security stuff server-side.
PHP Part
It is always a good idea to double-check each user input. Two steps are usually mandatory:
Validate user input: This is basically checking if user input is syntactically correct (for example a regex that checks if a user submitted text is a valid email address)
Escape database queries: Always escape dynamic data when feeding it to a database query. Regardless where it's coming from. But do not escape the whole query string, that could yield in unexpected results.
Maybe (and hopefully) you will like the idea of using an ORM solution. For PHP there are Propel and Doctrine for instance. Amongst a lot of other handy things, they provide solid solutions to prevent SQL injection.
Example in Propel:
$result = TableDataQuery::create()
->addSelectColumn(TableDataPeer::DATA)
->findByName($_POST['name']);
Example in Doctrine:
$qb = $em->createQueryBuilder();
$qb->add('select', 'data')
->add('from', 'TableData')
->add('where', 'name = :name')
->setParameter('name', $_POST['name']);
$result = $qb->getResult();
As you can see, there is no need for escaping the user input manually, the ORM does that for you (this is refered as parameterized queries).
Update
You asked if PDO is also an ORM. I'd say PDO is a database abstraction layer, whereas an ORM provides more functionality. But PDO is good start anyway.
can firebug any malicious code in opened in browser page and send
trash to php script that is somwhere on the server?
Yes, absolutely!
The only reason you do validation of user input in JavaScript is a more responsive user interface and better look & feel of your web applications. You do not do it for security reasons, that's the server's job.
There is a firefox addon to test your site for XSS, it called XSS Me
Also you can go to
http://ha.ckers.org/xss.html
for most XSS attacks
and go to
http://ha.ckers.org/sqlinjection/
for most sql injection attacks
and try these on your site