Prevent XSS Attack and encode correctly characters - php

i have the function for prevent sql injection
is an excellent function, really function in prevent attacks but
begin showing problems with characters
the word is "controle de finanças"
in var_dump i see string(31) "controle de finan&Atilde&sectas"
i´m trying some methods and failing 2 days please help me
function Anti_Sql_Injection($string){
if(ini_get('magic_quotes_gpc') == 'off'){
$string = addslashes($string);
}
$string = htmlentities($string, ENT_QUOTES);
$codes = array("script","java","applet","iframe","meta","object","html","CONCAT","CHAR","FLOOR","RAND", "<", ">", ";", "'","%");
$string = str_replace($codes,"",$string);
return $string;
}

Try this;
function Anti_Sql_Injection($string){
if(ini_get('magic_quotes_gpc') == 'off') {
$string = addslashes($string);
}
$string = htmlspecialchars($string, ENT_QUOTES,"UTF-8");
$codes = array("script","java","applet","iframe","meta","object","html","CONCAT","CHAR","FLOOR","RAND", "<", ">", ";", "'","%");
$string = str_replace($codes,"",$string);
return $string;
}
I also would like to tell you about PDO. It has built-in SQL injection via prepared statements. Check out this tutorial to start with PDO. I know it is kinda old but still valid and well explained.

Why are you using a function named Anti_Sql_Injection() to prevent XSS attacks? You should be using Prepared Statements to stop SQL injection and an appropriate, separate strategy for stopping XSS attacks.
Don't try to kill two birds with one stone. You end up altering data.
XSS prevention made easy
Are you using a framework that offers context-sensitive XSS escaping?
Yes: Use that feature then. Prioritize autoescape blocks over manual escape filters (e.g. with Twig).
No: Do you need to allow the user to provide some HTML?
Yes: HTML Purifier
No: htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');
SQL Injection prevention made easy
Use prepared statements. A library like EasyDB (which wraps PDO) can make it less painful to migrate.

Related

PHP SQL Sanitation VS Prepared Statements

Quick one.
I'm in the process of migrating an old web application that uses mysql to mysqli. I used to protect against SQL injection with a custom sanitation function I wrote:
function sani($text=""){
if (!is_array($text)) {
$text = str_replace("<", "<", $text);
$text = str_replace(">", ">", $text);
$text = str_replace("\"", """, $text);
$text = str_replace("'", "'", $text);
return $text;
}
}
They way I used to use this:
mysql_query("SELECT * FROM `table` WHERE `username` = '" . $sani($userinput) . "'");
Basically all it does is change symbols that can be used for injection into html encoding. It has worked fine up until now, but since i'm migrating to mysqli, I wanted to know if prepared statements would be more secure than this function.
Also, I have read a lot about the speed differences between prepared and unprepared statements, is it really that noticeable? I do around a hundred queries a second, so I doubt I would be affected very much?
Thanks!
Yes, prepared statements would certainly be more secure than this function, and they have the added benefit of not having to decode your data when you get it back from your database, too. By the way, even for the old mysql library, you really should rely on mysql_real_escape_string rather than your custom-built sanitation function :)
Prepared statements can be much faster than unprepared statements, and in a typical usage situation, you'll benefit from this even if you're "just" doing 100 queries/second.
The security of prepared statements originate in fact, that in prepared statements the query and data are sent separately. This is why it becomes impossible to perform 1st type of SQL injection (the 2nd type (or indirect) injections are ones that are caused if the query is concatenated from data in database).
The problem with your "protective function" is that it does not cover all cases. If you care to learn more about the issue, you could read slide from Slides From Recent Presentations on SQL Injection or slides on SQL injection: Not only AND 1=1.
Do not do that, ever.
Save the data as is using prepared statements so you always have the original data in your database even if it contains malicious code, no problem. In fact, you want that to see how they tried to hack you, or something.
Just create a simple filter when you output the unsafe (user submitted) data to replace the unwanted chars, such as < > etc.

How to prevent XSS attack in my function?

I am creating a function for my $_POST inputs to prevent SQL Injection BEFORE adding the values into database. I use it on login/register and when a user needs to post an article. As far as I know, this does not secure it from XSS.
Should I create a different function when I output data or edit this?
Thank you.
function clean($str) {
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
Try using prepared statements. They are designed to automatically escape things. They should also keep your queries cleaner in the source code.
http://www.ultramegatech.com/blog/2009/07/using-mysql-prepared-statements-in-php/
http://php.net/manual/en/mysqli.prepare.php
http://php.net/manual/en/book.pdo.php
You talk about XSS and then SQL injection...
SQL
Use mysql_real_escape_string() or better still bind params with a library such as PDO.
If magic_quotes is a possibility, use...
function sqlEscape($str) {
if (get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
Regarding your example, why do you need to use trim() to make data safe? Also, why use the error supressor on trim()?
XSS
Use htmlspecialchars($str, ENT_QUOTES) to prevent HTML special characters from having special meaning.
I use the following, which works just fine to prevent injections:
function clean($str) {
$value = mysql_escape_string(stripslashes(htmlspecialchars($str)));
return $value;
}
You shouldn't save values as encoded HTML to your database. Do that when outputting them, not when saving them (saving encoded HTML makes it harder to search in it, makes their size bigger, makes it harder to use them in formats other than HTML and generally just wrong - your database should store the actual text, not the text formatted to be displayed in a specific way).
Also, as Quamis said, you should probably look at PDO or some other DBAL that lets you use prepared statements instead of escaping it manually.

A PHP function to prevent SQL Injections and XSS

I am tring to make my PHP as secure as possible, and the two main things I am trying to avoid are
mySQL Injections
Cross-Side Scripting (XSS)
This is the script I got against mySQL Injections:
function make_safe($variable) {
$variable = mysql_real_escape_string(trim($variable));
return $variable; }
http://www.addedbytes.com/writing-secure-php/writing-secure-php-1/
Against XSS, I found this:
$username = strip_tags($_POST['username']);
Now I want to unite the two into a single function. Would this be the best way to do so? :
function make_safe($variable) {
$variable = strip_tags(mysql_real_escape_string(trim($variable)));
return $variable; }
Or does the mysql_real_escape_string already prevent XSS? And lastly, is there anything else that I could add into this function to prevent other forms of hacking?
mysql_real_escape_string() doesn't prevent XSS. It will only make impossible to do SQL injections.
To fight XSS, you need to use htmlspecialchars() or strip_tags(). 1st will convert special chars like < to < that will show up as <, but won't be executed. 2nd just strip all tags out.
I don't recommend to make special function to do it or even make one function to do it all, but your given example would work. I assume.
This function:
function make_safe($variable)
{
$variable = strip_tags(mysql_real_escape_string(trim($variable)));
return $variable;
}
Will not work
SQL injection and XSS are two different beasts. Because they each require different escaping you need to use each escape function strip_tags and mysql_real_escape_string separatly.
Joining them up will defeat the security of each.
Use the standard mysql_real_escape_string() when inputting data into the database.
Use strip_tags() when querying stuff out of the database before outputting them to the screen.
Why combining the two function is dangerous
From the horses mouth: http://php.net/manual/en/function.strip-tags.php
Because strip_tags() does not actually validate the HTML, partial or broken tags can result in the removal of more text/data than expected.
So by inputting malformed html into a database field a smart attacker can use your naive implementation to defeat mysql_real_escape_string() in your combo.
What you should really be looking into is using prepared statements and PDO to both provide an abstraction layer against your database as well as completely eradicate SQL injection attacks.
As for XSS, just make sure to never trust user input. Either run strip_tags or htmlentities when you store the data, or when you output it (not both as this will mess with your output), and you'll be all right.

Classes to Protect from SQL/XXS attacks? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 6 years ago.
I'm building a MVC application for managing a creative portfolio (Going to put it on git hub). I need something to secure the DB connections, basically I have one class to manage ALL DB transactions.
I need to either create a class or find a class that can protect all SQL queries from XXS or SQL Attacks. What suggestions do you have for securing PHP Database connections?
Using PDO's prepared statements to access databases makes queries immune to injection.
http://us2.php.net/manual/en/pdo.prepare.php
Using htmlspecialchars() makes output immune to xxs.
http://us2.php.net/manual/en/function.htmlspecialchars.php
just try to filter you POST,GET requests with this function
function protect($string)
{
if (ini_get('magic_quotes_gpc') == 'off') // check if magic_quotes_gpc is on and if not add slashes
{
$string = addslashes($string);
}
// move html tages from inputs
$string = htmlentities($string, ENT_QUOTES);
//removing most known vulnerable words
$codes = array("script","java","applet","iframe","meta","object","html", "<", ">", ";", "'","%");
$string = str_replace($codes,"",$string);
//return clean string
return $string;
}
you can easily apply it for the whole input using array_map function
$input = array_map('protect','$_POST');
$input = array_map('protect','$_GET');

should i still sanitise input with mysqli?

I'm using mysqli prepared statements. Should I still sanitise the user input with some function like:
function sanitise($string){
$string = strip_tags($string); // Remove HTML
$string = htmlspecialchars($string); // Convert characters
$string = trim(rtrim(ltrim($string))); // Remove spaces
$string = mysql_real_escape_string($string); // Prevent SQL Injection
return $string;
}
Thanks.
No! No and no. If you are already using prepared statements, MySQL needs to see the value, not some escaped version of it. If you add mysql_real_escape_string to a string and make that the value for a prepared statement, you have just junked it, for example, quotes get doubled up!
Now, as for sanitising data-wise, that's entirely up to the business rules as to what is or is not valid input. In your example, strip_tags is more about html->raw (format) conversion than sanitation. So is rtrim(ltrim - this is a business transformation.
Yes. When using prepared statements you are safe from mysql injections, but still there could be special characters, strip tags or spaces, so those you will still need to take care of those.
See PHP: Is mysql_real_escape_string sufficient for cleaning user input?
UPDATE:
You are safe from mysql injections so you should not use real_mysql_scape_string or scape any quotes.
Prepared statements are there to keep your query form being subverted by malicious input. But there's plenty of malicious content that is perfectly acceptable in an SQL query, but will attack a browser when redisplayed later.
Doing mysql_real_escape_string on data going into a prepared statement is generally redundant (there are exceptions, but they're special-ish cases).
Here is an Object orientated solution to your question:
public function sanitize($var){
if(is_array($var))
foreach($var as $k => $v) $var[$k] = $this->db->real_escape_string($v);
else
$var = $this->db->real_escape_string($var);
return $var;
}
You should always sanitize your user inputs before submitting them to the database. I would just stick with mysql_real_escape_string as the others are not that much necessary unless you are putting them back on the URL.

Categories