mysql_real_escape_string() for $_SESSION variables necessary? - php

Should I use the mysql_real_escape_string() function in my MySQL queries for $_SESSION variables? Theoretically, the $_SESSION variables can't be modified by the end-user unlike $_GET or $_POST variables right?
Thanks :)

Regardless of whether the user can modify the data, you probably want to escape it anyway in case you ever need the data to contain characters that would break the SQL (quotes, etc).
Better yet, use bound parameters and you won't have to worry about it.

Do not escape/quote/encode text until you're at the point where you need it. Internal representations should be as "raw" as possible.

You can answer the question yourself by following this line of reasoning:
Did the value in $_SESSION originate from user input?
If so, has it been sanitized already?

Theoretically, the $_SESSION variables can't be modified by the end-user
No, but the data must have come from somewhere.
You should escape any output from PHP, using the appopriate method for the destination at the point at which it leaves PHP.
C.

Related

PHP $_GET security, $_POST security best practice

It's a well covered topic, but I'd like to get some confirmation on methods of using data from user variables, in a few different situations.
The variable is never used in a database, never stored, only displayed on screen for the user. Which function to use to make sure no html or javascript can screw things up?
The variable is taken into the database, and used in SQL queries.
The variable does both.
At the moment I xss_clean, and strip_tags. I've always done this, just by autopilot. Is there a better technique? Apologies if there's an identical question out there. I kinda assume there is, although I couldn't find one as thorough as this.
Cheers.
Use the appropriate function while outputting, in HTML context, this is htmlspecialchars
Use prepared statements
See 1. and 2. – depending on whether you are displaying the variable or you are using it in a query.
One of worst delusions in the PHP world is that $_GET or $_POST have anything to do with security.
It is not the source but destination that matters
If you have to deal with database, the rules always the same, no matter if the data is coming from $_POST, SOAP request or a database. It has to be ALWAYS the same: placeholders for the data, whitelisting for the everything else.
If you have to output some data into browser, you have to properly prepare it, no matter whether the data is coming from $_POST, SOAP request or a database.
If you have to read from a file - you have to secure the filename, no matter where it coming from, and so on
In the first case htmlspecialchars() probably is the best choice, allowing for users to use all characters like <, >, &, etc.
In the second case you will need to use some database escaping function like mysql_real_escape_string or a prepared statement with PDO or mysqli. Prepared statements are the best choice here but if you are only familiar with mysql then mysql_real_escape_string works fine too. If you are not using mysql then there are similar functions in most SQL APIs.
In the third case do both but separately, with gives you two diffrent results, one for output and one for database.
References:
http://php.net/manual/en/function.htmlspecialchars.php
http://php.net/manual/en/function.mysql-real-escape-string.php
http://php.net/manual/en/book.pdo.php
http://php.net/manual/en/book.mysqli.php
$id="1;drop table users;"; $id=mysql_real_escape_string($id); $sql="SELECT * FROM table
WHERE id=$id";

PHP $_SESSION Simple securization issue

I am building a session array with 3 information: mail, password and id. mail and password i use from the POST. Note that before using the data i use mysql_real_escape_string for the mail and sha1 for the password. But for id I get the value from the database. The question is: Should I do 'id'=>htmlentities($data['ENS_ID']) instead of just 'id'=>$data['ENS_ID'] for security purpose? Sorry if my question makes no sense to you but I am a bit lost with securization. Thank you in advance for your replies. Cheers. Marc
$result = mysql_query("SELECT * FROM ENS_MEMBRES WHERE ENS_MAIL = '$mail' AND ENS_PASS = '$password'");
if(mysql_num_rows($result)==1){
$data=mysql_fetch_assoc($result);
$_SESSION['Auth']=array(
'mail'=>$mail,
'password'=>$password,
'id'=>$data['ENS_ID'],
);
You can store the ID in your session as as, but whenever you use it in another context, you have to escape it appropriately. That means:
when using in a database query, use prepared statements
when outputting in an HTML page, use htmlspecialchars
when using as part of an url, use (raw)urlencode
when executing external commands, use escapeshellarg, or escapeshellcmd respectively.
…
No, it should not be necessary. id should be of numeric type. Even if it was of another type, I personally would consider it better not to escape the value that you're storing in the $_SESSION, but rather escape it when you're doing something with it. Do you insert the value in HTML code -> use htmlspecialchars. Do you plan on using it in subsequent queries? Use mysql_real_escape_string and so on. In any case, the $_SESSION should really store the original value IMHO (i.e. not escaped). After all, you need different kinds of escaping depending on what you're doing with the value.
Just consider what would happen if you required the original (unescaped) id at some point, or have it escaped in a different way. It would be cumbersome to unescape the value that you have put in your $_SESSION.
--
Note that it is better to use PDO or similar for interacting with the database in any case, at least in the long run. With prepared statements and bounded parameters, you do not even have to escape the parameters yourself.
You are doing it wrong! mysql_real_escape_string should be used before putting the mail string into the SQL query, but you probably want to save it in its original form, without escaping, into the session array.
The same goes for the id (or anything you fetch from the database). Only escape data when it's time to use it. Escaping differs between different context, so escaping for HTMl (with htmlentities) may not be secure in SQL context and vice versa.

is it necessary to clean session before using them?

i always do a cleaning method for sessions before i use them an example would be
mysql_real_escape_string($_SESSION['username']);
the session only conains the id to the physical file that is stored on the server. how can this session be used client side to do malicious activity? is it then necesarry to clean the session before using it?
If you read user input from the session, then you have to sanitize it. If the user cannot influence the value (maybe a timestamp), there is no need to check it.
Sanitizing is necessary before you are using the value, e.g. before you output to an html page or before you use the variable in an SQL statement. To write to an HTML form you can use the function htmlspecialchars(), to use the variable for MySql SQL statements use the spezialized function mysql_real_escape_string().
You only need to use the mysql_real_escape_string function when you are querying a MySQL database.
When you say ID of the file, do you mean the the variable always contains an integer? If this is so then there is no reason to escape it as it is not a string.
If you do not know for sure what the session variable is going to contain, then you should always escape/sanitize it.

PHP: Is there any kind of sanitization I need for using _GET data?

For just regular use in my PHP code, that is. Not like I'm going to pass it to my queries or anything.
If you pass them to SQL queries, you get an SQL injection
If you use them to form file names, you get an arbitrary file reading vulnerability
If you output them as-is to the user as a part of HTML page, you get an XSS vulnerability
If you output them to a file, you may get a malformed file if it has some predetermined formatting
If you're just comparing the value with a set of predefined values, you're fine.
If you're converting it to a number, you're fine as long as any number works for you
This can really be answered only by stepping through your code, and looking exactly what it does. There could be pitfalls in your code (like a badly built switch statement) that could require sanitation.
Other than database queries, general scenarios where you need to sanitize incoming data include:
Using it in a file name
Using it to include a file
Using it to pass parameters to a program executed through exec()
Outputting it to HTML
You need whatever your application and its security require, keeping in mind that you can get absolutely anything (or nothing) in a $_GET parameter. Maybe you are not using the value in queries, but you may be subject to a cross-site scripting attack if you blindly use a value in a page, for example. "Harmless" websites can easily fall into a cross-site scripting attack.
Never trust user input, yes?
You need to sanitize variables depending on the content of them and the use of them.
so if you have a variable like so:
$_GET['page_id']
And your using within the database, then your sanitize it.
if you have a variable like so:
$_GET['action']
And your planning on using like
require_once "pages/" . $_GET['action'] . ".php"
then you sanitize before you do that, otherwise just make sure that register_globals is off and you will be ok aslong as your not using them in places without considerable thought
Everything that's is not coming from your server should be sanitized! This includes $_GET, $_POST, $_SERVER just to name a few.

Sanitizing PHPSESSID

I'm passing PHPSESSID to a PHP page (via POST) and I was wondering what's the best way of sanitizing the input. Would mysql_real_escape_string suffice? Is there anything special I should take into account when dealing with session IDs (I mean, they can only be letters and numbers right?)?
EDIT:
To clarify the question, what I really want to know is: if someone tampers with the POST data, can he send a malicious string as PHPSESSID that would do something nasty when I call session_id($_GET['PHPSESSID'])?
I personally cannot think of any, but better safe than sorry...
Thanks
nico
Good thinking, but as far as I can see, there is no need to sanitize this input. The PHPSESSID will be passed on to session_id().
session_id indeed has some limitations:
Depending on the session handler, not all characters are allowed within the session id. For example, the file session handler only allows characters in the range a-z A-Z 0-9 , (comma) and - (minus)!
But session_id() should deal with deviations from these rules with an error message. (You may want to catch that error message and terminate the script on error.)
The only real danger that I can see is when you use a custom session handler that e.g. connects to a database. You will have to sanitize the input in that case, e.g. using mysql_real_escape_string(). However, that is something that should take place inside the custom session handler.
It goes without saying that if you use the session ID in some other context - say, as a parameter in a HTML form - you need to take the sanitation measures necessary for that specific output (In that case, htmlspecialchars()).
If you really need to pass on a session ID via POST (can´t see why really...) and you know what characters you want to allow, I would use a regular expression to check for that.
mysql_real_escape_string is for database input and requires a database connection and is not sanitizing anything, just escaping some special characters.
Would mysql_real_escape_string suffice?
Wrong. You should always sanitize data using an appropriate method to the place you are writing the value to. You'd only use mysql_real_escape_string() if/when you are writing a value to a MySQL database.
It's not clear from your comment what exactly you are doing. Do you mean you are using curl in PHP to create the POST? If so then there's no sanitization required (not strictly true - but curl does it for you) if you pass CURLOPT_POSTFIELDS as an array - but you need to urlencode the value if you are passing CURLOPT_POSTFIELDS as a string.
Are you writing the value out to the browser so the user can submit the value? In which case you'd use htmlentities() to write the value into the form field.
Something else?

Categories