"We should never trust user's input", this is what I read from somewhere on the web.
Currently I have a web form, they enter their username and emails. For username field, how to control, check and prevent mysql injection?? Currently, in my php script I only do this:
$username = mysql_real_escape_string($_POST['username']); // prevent mysql injection
I saw some tutorials, before the mysql_real_escape_string function, they include other functions like, htmlentities, etc (could not remember what it is, and I cant found it now, sigh)
Is this a must to include the so called "htmlentities" function before mysql_real_escape_string??
What is your method you usually use for checking user's input data?
Oh ya, some other functions:
stripslashes();
serialize();
urlencode();
Must i include those?
You're doing it right, as far as putting your data into the database is concerned. You're protected against SQL injection attacks.
htmlentities() and htmlspecialchars() aren't relevant to SQL injection attacks; they're relevant to XSS attacks, which is a whole other topic you should look into, and is a relevant issue if you're displaying user input back out to the web.
You could also look at using prepared statements (I think equivalent to parameterized queries for SQL Server), which further reduces the attack surface.
like #chaos said is right
you can also use database abstraction layers, like pdo that will escape the paramaters for you
Related
i read it some where in form that xss clean in codeigniter dosn't not prevent in sql injection and it should not be used in input but it should be used in output it is true... Please can any one explain.. then how to prevent from sql injection in codeigniter.
Thank you for replaying me..
and sorry for the bad english..
First of all, both topics are not specific to CodeIgniter.
But CodeIgniter has specific way to handle some of this. Please read https://ellislab.com/codeigniter/user-guide/general/security.html
Remember that CodeIgniter will not save you from any of these and you must understand how both of these attacks works.
It is important to understand these are two different attacks, as with any attacks, they could be coupled together. For example using a XSS/CSRF to perform a SQL injection via. a crafted link to a administrator or etc.
XSS is when the attacker can inject code to be executed on the clientside. For example placing a <script> tag in your code. This often happens if you output data which the user has provided without sanitizing it or validating it. Typically this could be their username, a post title, $_GET data and etc. There are alot more ways to get a script executed on the clientside other than a script tag, so make sure to read up on the subject.
To avoid it, always escape user inputted data, from any source.
You can read more about it https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
SQL injection is when the attacker can change the SQL query for a malicious purpose. The most common way to avoid injection is to make sure to escape every input, before passing it to a query. Using prepared statement also helps alot. In CodeIgniter, you often use the "ActiveRecord" db thing, which escapes the input for you.
You can read more about it, including examples https://www.owasp.org/index.php/SQL_Injection
You should also read https://www.owasp.org/index.php/Top_10_2013-Top_10 and become familiar with the most common attacks.
In my php code i can get data with php $_GET method. Here is code look like this..
<?php
<a href='userprofile.php?uname=$uname'>$uname</a>
?>
If i click the the link it's show user profile page and so that userprofile.php page's url look like this.
http://localhost/evantechbd1/userprofile.php?uname=shibbir
My question is how do i prevent this url from sql injection or any other attack.
If I write:
http://.......uname=shibbir'OR'='-1-'
then it's show:
SHIBBIR%27OR%27%3D%27-1-%27'S PROFILE.
BUT I want whatever text is provided to that link it's must be show only valid username profile page.
Any idea.
The best way is to use a prepared statement, see the examples here, although I normally do some data validation even on data that is going to be used in a prepared statement.
For example, if someone registers, there are only certain characters allowed in a username and I use that same check when someone enters a username to be fetched.
You can't prevent someone from ATTEMPTING the attack, you can only prevent the attack from succeeding. However, what that prevention actually IS depends entirely on what you're going to use the database. There is no 'magic bullet' function that will make every bit of data safe in every case, as many 'sanitization' functions destroy data that is necessary in other usage cases.
e.g. there is no point in doing an SQL injection attack prevention with (say) mysql_real_escape_string() if the bad data is never going to be used in an SQL query. Doing htmlspecialchars() when the string is not going to be used in HTML context is similarly useless.
Before using $uname in your SQL, escape it.
For example, if you use the old but gold PHP MySQL extension:
$uname = mysql_real_escape_string($uname);
$res = mysql_query("SELECT * FROM users WHERE name = '$uname'");
If $uname is shibbir'OR'='-1-', after using the function I wrote, it will be shibbir\'OR\'=\'-1-\', that is unable to break your query.
Read more here:
http://php.net/manual/en/function.mysql-real-escape-string.php
http://www.php.net/manual/en/security.database.sql-injection.php
The other issue then is cross site scripting exploits. There are several ways of dealing with this but the usual way is to check that $_GET[ 'uname' ] exists as a username in your database first before using it in the html block.
I read a lot about filtering data which my web site get from user to make web site secure in sql injenction and xss . . .
but I saw a lot function in php so I can't make decide what to do . . .
please help me make it more secure
You're asking a couple questions here, so I'll try to break it down:
SQL Injection
Problem
This can occur when you pass user input directly to the database, something like this:
$query = "SELECT * FROM Table WHERE field = " . $_POST['field'];
$result = mysql_query($query);
The user can put whatever they want into the 'field' field on the form, and the database will execute it. This means a user could enter a malicious string which prematurely terminates your intended query and then runs a query of their own.
Solution
Don't directly construct your queries with user input. Instead, you should look into using prepared statements (This is typically handled with the PDO library). Prepared statements can take several forms, but they all involve using placeholders in the actual query string to tell the database where to stick other data you'll pass in later. That way the database can handle any appropriate escaping itself. The code would look a bit like this:
$statement = $db->prepare("SELECT * FROM Table WHERE field = :field");
$statement->bindValue(":field", $_GET['field']);
$statement->execute();
In this case, :field indicates the placeholder for the value later supplied by bindValue. PDO will take care of the escaping as needed.
That said, you should still sanitize any user data as needed.
XSS
Problem
Cross-Site Scripting, or XSS, occurs when unsanitized user input is passed directly back to the browser. If the user entered JavaScript commands, these commands could be executed in another users browser, possibly allowing the original hacker to gain access to that users credentials.
Solution
Rather than going into a lot of detail here, I'll simply say that this can be avoided by setting the HttpOnly flag on any cookies you set, so that they cannot be accessed in JavaScript (malicious or otherwise), and by never, ever echoing back unsanitized inputs to a user.
Sanitizing User Inputs
PHP has some nice features built in for sanitizing many forms of user input. I'll simply recommend that you check out the filter_var function and the various filters it can apply.
Never just echo user input back to the user. You should do your best to validate your inputs and reject anything that doesn't conform, but for inputs you need to display back to the user, always use something like htmlentities(). For a heavier but much more thorough option, you can take a look at the HTML Purifier library.
Hope that gets you started in the right direction.
Most SQL injections can be prevented with mysql_real_escape_string(), assuming you're running MySQL. Other database systems also have similar functions.
Protecting your site from XSS attacks is more complicated. The simplest way to prevent javascript code injection is stripping away all HTML tags with strip_tags(), but that will prevent using harmless tags like <b> as well, though they can be whitelisted if needed.
The only generic advice I can give you is to learn:
Prepared statements to avoid SQL injections
A custom markup languages like StackOverflow is using to avoid XSS attacks
OK consider this url:
example.com/single.php?id=21424
It's pretty obvious to you and i that the PHP is going to take the id and run it through a mysql query to retrieve 1 record to display it on the page.
Is there anyway some malicious hacker could mess this url up and pose a security threat to my application/mysql DB?
Thanks
Of course, never ever ever consider a user entry (_GET, _POST, _COOKIE, etc) as safe.
Use mysql_real_escape_string php function to sanitize your variables: http://php.net/manual/en/function.mysql-real-escape-string.php
About SQL injections : http://en.wikipedia.org/wiki/SQL_injection
All depends on the filtering you explicitely (with filter_var() for instance) or implictely (by using prepared statements for instance) use.
Well there is Sql injection
http://en.wikipedia.org/wiki/SQL_injection
Is mysql_real_escape_string() with sprintf needed only at login page or at every mysql_query after login, for preventing SQL injection?
You should use mysql_real_escape_string() every time you insert user-posted data into a query, or use a database wrapper like PDO that can do prepared statements. That would be better, because they do the job of sanitizing for you.
If you are working on the overall security of your site, this is great and definitely necessary. If you are looking for reasons why your site was hacked, though, I doubt this was done through a SQL injection, as your actual HTML code was affected (or so I thought, I may be wrong). This would be only possible if you had your FTP password stored somewhere in the database.
You should use mysql_real_escape_string for any user supplied data that is going to be ran through an SQL query.
Use it when you do not trust the input. And never trust a user input.
In any instance that you accept user input, you should use mysqli_real_escape_string on it before sending it to the database. It is a good idea to use trim() on the input as well.