Page 1 of 1
Simple Question: Session Security
Posted: Tue Oct 16, 2007 12:45 pm
by ctown82
I'm storing a few things in a session. My question is, do I have to sanitize this data?
Is it possible to corrupt or poison a session?
(Assume that I'm using this in a DB query.)
Posted: Tue Oct 16, 2007 1:07 pm
by Christopher
If the data comes from an untrusted source, then yes. It does not matter by which route the data gets to where there an exploit can occur. Indirect routes, such as from the request to the session and then into a SQL statement, are the hardest to trace. That is why Defense in Depth is the best practice.
Posted: Tue Oct 16, 2007 3:01 pm
by Mordred
No, you don't.
Your session handling code should take care of that - whether it's the default file-based sessions (which can take anything, so no additional measures are needed) or your custom DB-based code.
While arborint is correct in depicting some of the dangers, he is not correct in the solution. I'll give you an easy explanation: how would you prevent SQL injection and XSS by pre-sanitizing the data kept in the session. Would you first mysql_real_escape_string() and then htmlentities() or the other way around? Would John O'Brian be inserted in the database as John O'Brian, or would his name be displayed as John O\'Brian?
When you need to put the data - any data - in the database, escape it as appropriate for database usage.
When you need to put the data - any data - in the output html, escape it as appropriate for html usage.
Anything else is not defense in depth, but a data flow bug, not any different than using magic_quotes.
Posted: Tue Oct 16, 2007 3:39 pm
by ctown82
Thanks.
I wrote a strict sanitation function that strips all but number and/or letters. It also accepts additional characters, should I feel that they be needed, but not by default.
This works for everything I've written so far.
Posted: Tue Oct 16, 2007 5:36 pm
by Christopher
Mordred wrote:While arborint is correct in depicting some of the dangers, he is not correct in the solution.
I did not propose a solution. Defense in Depth would imply that you sanitize before assigning to the session AND sanitize and escape when generating SQL.
Posted: Wed Oct 17, 2007 3:14 am
by Mordred
Hmm, I may be wrong in calling it a "solution" then, but you did give an answer.
I challenge your oppinion that you need to sanitize session data, and I explained that in my view it is a bug. I can't see a sensible way in which to escape the data without causing a problem somewhere. Can you give an example what would you do to session data?
Edit: Oh, wait, maybe we have a terminology disagreement. Does "sanitize" mean "escape" (like in mysql_real_escape_string()) or "validate" (like in "if (strlen($_GET['a'])>56) ...")
Posted: Wed Oct 17, 2007 10:38 am
by John Cartwright
I'd assume the latter.
Posted: Wed Oct 17, 2007 11:52 am
by Christopher
I used the OP's term sanitize, by which I meant filter and validate. Escaping would be done only at the point that the SQL was being created -- (and possible filtering and validating as well). That is assumed to be just before the query, but you could technically save the SQL in the session for some reason.
The point of Defense in Depth is that at every level and in every subsystem you take appropriate security measures, and do not assume that a higher level has done them. That would help against untrusted values going to the session and then to the database ... with the programmer assuming that data in the session was ok (e.g. not an untrusted superglobal).
Posted: Mon Oct 22, 2007 3:40 pm
by ctown82
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
This is the function I use most of the time:
Code: Select all
define('NUMBERS_ONLY', "[^0-9 ]");
define('LETTERS_ONLY', "[^a-zA-Z ]");
define('NUMBERS_AND_LETTERS', "[^0-9a-zA-Z ]");
function FxSanitize($original_string, $allowed_chars = "[^a-zA-Z0-9_,. -]")
{
return ereg_replace($allowed_chars, "", $original_string);
}
The default allowed characters are pretty lenient, but strip things like quotation marks and double quotes. The others are when I'm expecting to get specific data back.
This is good for most things, IMO, but can be annoying for users writing into a 'Notes' section. That's fine for my current application.
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Posted: Tue Oct 23, 2007 6:54 pm
by CoderGoblin
Session Fixation PDF is an interesting read.