php query string validation - php

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.

Related

Can someone perform a SQL Injection based on session variables in php?

Basically I am making a web application and I am going through the security of it to make my app as robust as I can.
Once you're logged in to my app I track that user based on session variables.
When SQL is performed it takes the users session variable to see who they are for example.
$name = $_SESSION['user_name'];
A example query would be something like this..
$query1 = "SELECT * FROM tableName WHERE userName = '$name'";
From reading online sites say things like I must not use "user input in SQL statements." Am I right in thinking that because I am using session variables the user does not have direct access to the sql statement or is session variables still "user input"?
If not should I just go through the normal SQL Injection prevention methods like...
Input validation (authenticating the data based on length, syntax
etc)
Checking user privileges making sure users have the least
privileges.
ect..
Thanks in advance for any comments anyone makes.
It doesn’t matter where the data came from as in any case you have to ensure that the data is interpreted as intended.
And one of the easiest way to ensure that is using parameterized statements, where the SQL code and parameter values are passed separately so that a parameter value can’t be mistakenly interpreted as SQL.
Prepared statements implement this parameterization, either native or emulated. With them you don’t have to worry about whether a value may be influenced by a user’s input.
Always escape input. What if their name is "David O'Connor" or something.
This name is assumedly user supplied, so do it.
Anyway, you shouldn't be directly issuing SQL queries, a function should be building them for you (or an ORM).
Am I right in thinking that because I am using session variables the user does not have direct access to the sql statement or is session variables still "user input"?
The problem you might have in your example is that the username might be something controller by the user. They might be able to change it or choose it depending on your application requirements.
I think the simplest way to prevent surprises is stop thinking too much and just protected your queries agaisnt SQL Injection.
I'm no expert on PHP, but I think you have prepared statements that will help you dealing with this security issue. Just use it. (it should be a slogan, "prepared statements, just use it." :D)
Any login/create-user page you have should do input validation before writing the userName column in your database and writing $_SESSION['user_name'].
AFTER that, your $_SESSION variable is safe. You have to do validation checks somewhere in the process:
Input -> store in database/session -> use
I recommend at the 1st arrow. Then the code snippets you wrote in the question are perfectly fine.
Am I right in thinking that because I am using session variables the
user does not have direct access to the sql statement
correct. $_SESSION-vars are stored on your server-filesystem and unless you introduce user-input ($_GET & $_POST, for example) into them there is no actual way of manipulation for these. If you generate $_SESSION['user_name'] without actual userdata you're well off. The hard part is getting the username without parsing input - one would be advised to use HTTP-data-filtering frameworks for these kinds of jobs.

php login authentification token_id and login script found on the net - secure?

While making my new site i needed new login script, so i can feel comfortable with my data. I made such scripts earlier, but who knew how secure they were. Hoping to find some anwer on the web i found such a tutorial that calls itself 'super secure login script'. You can find it in this link
I wonder how secure it really is, and what kind of threats is it vulnerable.
I also found in code lines like this:
// Create Second Token
$tokenId = rand(10000, 9999999);
$query2 = “update users set tokenid = $tokenId where userid = ‘$_SESSION[userid]‘”;
$result2 = mysql_query ($query2);
$_SESSION['token_id'] = $tokenId;
How should it work? What is it preventing from? Should i compare $_SESSION['token_id'] with something later or what?
The code you posted is simply creating a random number, then storing it on the user record in the users database table, then storing it in the session.
Based on the link provided, the token or random number doesn't actually get used for anything at all. You'll have to ask the developer for the meaning of that.
I wouldn't recommend the login script you linked to for these reasons:
1) The way it escapes user input to avoid SQL Injection
Here is the function that is used:
function escape_data ($data) {
// Check for mysql_real_escape_string() support.
// This function escapes characters that could be used for sql injection
if (function_exists(‘mysql_real_escape_string’)) {
global $dbc; // Need the connection.
$data = mysql_real_escape_string (trim($data), $dbc);
$data = strip_tags($data);
} else {
$data = mysql_escape_string (trim($data));
$data = strip_tags($data);
}
// Return the escaped value.
return $data;
} // End of function.
The above function has some problems. The biggest being that if it finds that mysql_real_escape_string() does not exist, it falls back to mysql_escape_string(). You should never fall back to mysql_escape_string(). If mysql_real_escape_string() is not available and you're relying on it to avoid SQL Injection, your application should stop.
The other problem with this is it is uses strip_tags(). Escaping for SQL Injection and escaping/encoding for XSS are two different things and shouldn't be combined into one.
I suggest using MySQLi prepared statements or PDO parameterised queries instead of this function, to avoid SQL Injection.
To avoid XSS, use htmlentities() whenever content from the database (or direct user input) is printed out which originated from user input.
2) This is bad practice
$_SESSION[userid] // this should have single quotes, making it $_SESSION['userid']
3) PHP logic and HTML are mixed in together, no effort is made to separate them.
4) CAPTCHA on the login form. This is just going to make users unhappy. Usually there is no need for a CAPTCHA on a login form.
Edit - here I've responded to some of your points in the comments.
Author's intention for token
It's anyone's guess really but perhaps the random number was meant to be used in a password reset link.
For that sort of thing, hashing the random number/string is usually done rather than keeping a short random number. Also mt_rand() is better than rand().
Using a single function for SQLi escaping and XSS prevention
This is a bad idea because they are two very different things. Escaping for SQLi is done inbound to the database, XSS prevention should be done outbound if you see what I mean.
When storing data in the database, it is usually best stored in raw form rather than having it had strip_tags() or htmlentities(). What if at some point you want to allow HTML to be entered into the database for any reason?
The XSS prevention should be done as the data comes out of the database and onto the page or where ever it goes to. What if you want to output the data to another medium other than HTML, like XML or to a web service, and you've already processed it for HTML.
A single function for both XSS and SQLi doesn't make the code cleaner, it applies processes to data that don't need to be applied at that time.
Look at any popular framework such as Zend, or CMS such as WordPress, Joomla etc. None of them use a single function for both SQLi and XSS.
Mixing PHP and HTML
Yes you're right it isn't going to affect security but it just looks terrible. It is hard to read, hard to maintain, hard to extend and update, and definately remains a reason I would not recommend it.
Quotes in $_SESSION['userid']
Using $_SESSION[userid] inside a query to solve the problem of the query breaking due to quotes, shows lack of knowledge/experience.
You can use quotes, you just need to concatenate the variable into the query like
$sql = "SELECT * FROM table WHERE something = '" . $_SESSION['something'] . '";
Of course you need to escape for SQLi (preferable using parameterised queries) if you're unsure of the contents of the variable.
CAPTCHA
CAPTCHA is great when used in the right places. A login form like this is not one of them. You could use a CAPTCHA after X failed attempts (as Google do), but not like this where it is required all of the time.
There are other ways of dealing with brute force login attempts, several answers here on SO.
Another point that I didn't mention is the password hashing. That is using SHA1 with no salt, which is not very strong. I would use SHA256 or higher and use a salt for passwords.

best way to filter data from user(xss and sql injection)

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

piece of php code for prevent hacking

I have a php file at my site, and I connect to db, get some records and list them in same file.
mysql_connect("localhost", "blabla", "blabla") or die(mysql_error());
mysql_select_db("blabla") or die(mysql_error());
$blabla1 = mysql_query("SELECT * FROM gallery WHERE id_cat=1");
$blabla2 = mysql_query("SELECT * FROM gallery WHERE id_cat=2");
$blabla3 = mysql_query("SELECT * FROM gallery WHERE id_cat=3");
So, is there anything I need to do for security? Like sql-injection or anything else. there is nothing going to url. It is just www.blabla.com/gallery.php.
This snippet is perfectly safe, because there are no variables put into the query string.
To work safely in case you have to deal with variables one day - be they directly coming in from the user, or from another data source - you may want to switch over to a mySQL library that supports parametrized queries, like PDO. Those eliminate the danger of injections completely, because they take care of escaping the incoming data automatically.
If you stick with the mysql_* functions, make sure you escape all incoming any data using mysql_real_escape_string() and ensure they are inserted within a pair of single quotes.
As long as your queries don't use parameters, SQL Injection is not a risk.
SQL Injection can only happen when the users (or other sources) can influence anything that is send to the database in SQL, for example searchwords
There are no security issues here. SQL injection might happen where you get input from the user and use it in your queries.
if gallery table contain some user input, then some XSS attack may be conducted. To prevent this, all untrusted user input must be prepared using htmlspecialchars() function before printing to the browser.
This snippet is safe, as there is no user provided input in the queries.
if you have userinput, for example by getting the category that should be displayed from the URL or from POST you should use prepared statements. this may you are safe even with user input. This is much safer than pure escaping because the sql is parsed and then the parameters are inserted. This is better for performance and the userinput can't change the structure of the sql query.
The only thing that you might want to consider, assuming that the connection code is in the web-accessible PHP script, is to either:
move the MySQL connection out of the
script and into a file outside of
the site's document root
or, use externally-sourced variables
(i.e. from a different file outside
of the document root) for the
username and password in place of
hard-coded details in the script
That way if, for whatever reason the server displays the code instead of rendering the PHP, then the details will remain safe from view

What are the methods to check user input and prevent mysql injection?

"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

Categories