Whats Your Security Regimen ?

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
Live24x7
Forum Contributor
Posts: 194
Joined: Sat Nov 19, 2011 9:32 am

Whats Your Security Regimen ?

Post by Live24x7 »

I am updating myself on PHP security issues for the last 2 days.
Here is a gist of things that I have collected from various sources to do as a part of my security regimen:

1. Use $_POST variable instead of $_REQUEST
2. Check all user inputs with regex (even the drop-down boxes, radio buttons, checkboxes to avoid form spoofing)
3. mysql_real_escape_string() to avoid SQL injections
4. htmlentities() - to avoid XSS attacks
5. keep url parameter different from actual field names in database
6. rewrite url to clean url (to hide parameters)
7. remove .php extension with .htacess
8. session token to prevent session hijacking
9. error_reporting turned off in a production site
10 register_globals disabled on production site
11 Initialize all variables in scripts
12 Avoid specifying dynamic paths in include, require etc like include ('$path/abc.php');
13 put single quotes around all values in your SQL statements

I have not mentioned password encrypting in the list because am yet to update myself after the MD5 debacle.
I know this can be a never ending topic but anything vital that i am missing ?
User avatar
Christopher
Site Administrator
Posts: 13595
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Whats Your Security Regimen ?

Post by Christopher »

1. Use $_POST or $_GET. The reason for avoiding $_REQUEST is that POST/GET variables can overwrite depending on the configuration settings.

3. Don't use the mysql extension. Use mysqli or PDO instead.

5-7. Not sure these are real security measures, but can't hurt.
(#10850)
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Whats Your Security Regimen ?

Post by requinix »

2. Regex is expensive. Check that there isn't already a function that does what you need; often overlooked functions are ctype_digit for positive integers, ctype_alnum for alphanumerics, and is_numeric for numbers.
4. htmlentities() for HTML, htmlspecialchars() for XML.
5. Use what's sensible.
6. Not really a security thing.
7. Doesn't matter.
10. And development servers too. Dev should be as close to prod as possible.
12. You can if you're very careful about it.
13. Not really a security thing: you have to quote strings. Single or double? Doesn't matter if you're escaping the values properly.

Also
- Whitelists (using known good values) are better than blacklists (not using known bad values)
- CSRF tokens on important forms (wouldn't hurt for all forms too)
- Upload directories (a) outside the web root and/or (b) carefully protected against file execution and/or (c) inaccessible except through a "download" script
- Other stuff that I'm not thinking of
Live24x7
Forum Contributor
Posts: 194
Joined: Sat Nov 19, 2011 9:32 am

Re: Whats Your Security Regimen ?

Post by Live24x7 »

ctype_digit, ctype_alnum are new for me - but should be useful.
htmlspecialchars() for XML - will keep in mind

CSRF tokens on important forms - will keep this in mind. My security needs are not very high as i essentially do small projects where costs of development are rather low but hope to implement this wherever the cost can be justified.
requinix wrote: Upload directories inaccessible except through a "download" script
I did not understand what this means :roll:
requinix wrote: 13. Single or double? Doesn't matter if you're escaping the values properly.
What i meant is that putting single or double quotes around all values before putting them in your SQL to prevent sql injection.
requinix wrote: 5. Use what's sensible.

Isn't it better to keep url parameters different actual field names in database ?
Christopher wrote: 5-7. Not sure these are real security measures, but can't hurt.
I thought they would help in security through obscurity ?

Thanks for your replies.
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Whats Your Security Regimen ?

Post by requinix »

Live24x7 wrote:
requinix wrote: Upload directories inaccessible except through a "download" script
I did not understand what this means :roll:
(If you pick option c:) If you have an uploads directory at (for example) http://www.example.com/uploads you shouldn't allow people to get there directly. It means that as soon as they upload a file they can access it, which may also include running .php scripts. So make sure you have Apache configured, one way or another, to disallow access to that folder. To get files "out" of it you write a download script that outputs the file (which means you can put whatever kind of restrictions you want in there).
Live24x7 wrote:
requinix wrote: 13. Single or double? Doesn't matter if you're escaping the values properly.
What i meant is that putting single or double quotes around all values before putting them in your SQL to prevent sql injection.
Right. That's not about SQL injection. You have to put quotes around strings. Just like you have to put quotes around strings in PHP. It's part of the syntax.
Live24x7 wrote:
requinix wrote: 5. Use what's sensible.

Isn't it better to keep url parameters different actual field names in database ?
Why? What does it gain you that you haven't already worked around? SQL injection? Already covered. Database and server access? I sure hope that's not an issue. Guesswork on the end of the user? Can't stop that.
Lemme guess: you have a "users" table with a "username" column? That won't do me any good unless there are other exploits I can make use of. So spend your time worrying about those first.


Obscurity is not real security. It adds a little bit to the real security mechanisms you already have. Access control, file permissions, user rights... those are forms of real security. Changing session cookie names and using unusual URLs for protected pages offer a false sense of security: once those are revealed then it's all over.
You have to weigh the pros and cons. If it's cheap and easy then sure, add some obscurity. But if you have to sacrifice maintainability, or ease of use, or backwards compatibility, then it's probably not worth it.
Live24x7
Forum Contributor
Posts: 194
Joined: Sat Nov 19, 2011 9:32 am

Re: Whats Your Security Regimen ?

Post by Live24x7 »

I indeed have a user table with username field. :)

Thanks for your clarifications. All points taken
User avatar
Celauran
Moderator
Posts: 6425
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Whats Your Security Regimen ?

Post by Celauran »

Live24x7 wrote:3. mysql_real_escape_string() to avoid SQL injections
Prepared statements with bound parameters to avoid injection.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Whats Your Security Regimen ?

Post by VladSun »

There are 10 types of people in this world, those who understand binary and those who don't
global_erp_solution
Forum Commoner
Posts: 25
Joined: Sun Jul 08, 2012 6:47 am

Re: Whats Your Security Regimen ?

Post by global_erp_solution »

scuse me,
1.I don't really understand the XSS attack part. htmlentities() is useful only when you're trying to render HTML input to client's browser, correct? so when data flows out from the server into client? Suppose I never manipulate browser's DOM (because all server response are in text form), is it safe to say that my web app is immune to XSS attack?
2. as for SQL injection and mysql_real_escape_string(), I thought escaping and wrapping the input string from user input is enough? I just do 4 things to achieve this objective :

Code: Select all

1. change all single quotes to \'
2. change all backslash to double backslash
3. change all double quotes to \"
4. wrap strings in single quotes
that's all
3. for session related, I just perform session regeneration, set session timeout and disable the url containing session (forgot the name). so always use cookies.

With these, does my app still have vulnerabilities? thanks
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Whats Your Security Regimen ?

Post by requinix »

global_erp_solution wrote:1.I don't really understand the XSS attack part. htmlentities() is useful only when you're trying to render HTML input to client's browser, correct? so when data flows out from the server into client? Suppose I never manipulate browser's DOM (because all server response are in text form), is it safe to say that my web app is immune to XSS attack?
If you are rendering text/html then you are vulnerable. The point is that someone could put HTML into a string, so when you echo it you're unintentionally adding to the DOM.
global_erp_solution wrote:2. as for SQL injection and mysql_real_escape_string(), I thought escaping and wrapping the input string from user input is enough? I just do 4 things to achieve this objective :

Code: Select all

1. change all single quotes to \'
2. change all backslash to double backslash
3. change all double quotes to \"
4. wrap strings in single quotes
that's all
If the order is 1,3,2,4 (or 3,1,2,4) then that's great, but it doesn't account for Unicode characters. But really, would you rather have a few calls to str_replace() that you have to manage by yourself, or one call to mysql_real_escape_string(). Putting aside the "use prepared statements" argument for a minute, of course.
global_erp_solution wrote:3. for session related, I just perform session regeneration, set session timeout and disable the url containing session (forgot the name). so always use cookies.
Depending on the regeneration, possibly. Hypothetically a malicious eavesdropper could hijack a user's session so you still have to (do what you can to) protect yourself against that (by including information in the session that can more-or-less identify a user's computer and/or browser).
global_erp_solution
Forum Commoner
Posts: 25
Joined: Sun Jul 08, 2012 6:47 am

Re: Whats Your Security Regimen ?

Post by global_erp_solution »

the text here means the server only returns AJAX text response to be parsed into JSON, so no renderring. Other type of server's text response is URL that will be executed using Header location..

as for mysql_real_escape_string(), do you mean this one function accompanied with prepared statement is the silver bullet to thwart all kinds of SQL Injection? that's great news. Will that work to all database vendors (oracle, sql server, postgre, etc)? because I always thought, as the name implies, only works for mysql

you also said about the session regeneration that it's still possible to hijack the session? if so, could you elaborate a little bit? a little code would be appreciated. Thanks
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Whats Your Security Regimen ?

Post by requinix »

Okay, so PHP isn't doing any rendering. So the next question is whether your JavaScript does. If so then you're potentially vulnerable (depending how you do the rendering).

As you saw, mysql_real_escape_string() is for MySQL only, but most of the other vendors have a similar function. Prepared statements are the alternative; arguably meant for a different purpose, you can use them to be 100% safe from SQL injection. Either you construct queries by hand and use mysql_real_escape_string() or you use prepared statements. One or the other but not both (for the same query, that is).

As for session regeneration, the malicious sniffer has at least two options:
1. Intercept a session ID and fire off a request before the original user can send their next one. This can allow for concurrent browsing if you aren't completely destroying old sessions and aren't ensuring one session per user.
2. Wait until the user has stopped browsing and resume where they left off.
global_erp_solution
Forum Commoner
Posts: 25
Joined: Sun Jul 08, 2012 6:47 am

Re: Whats Your Security Regimen ?

Post by global_erp_solution »

for the sql injection part:

let's say I'm using mysql, so the code would be something like:

Code: Select all

function sanitizeInput($dataToBeSanitized){
    return mysql_real_escape_string($dataToBeSanitized);
}
and the DB code 1:

Code: Select all

function insertMe($data){
    $query='SELECT * from TABLE1 where ' . sanitizeInput($data);
    //do something with the query
}
or DB code 2, this one is without mysql_real_escape_string:

Code: Select all

function insertMe($data){
    $stmt.bindParam(:param1,$data); // here $data is not sanitized
}
and that's it right? both DB code 1 and 2 are now 100% sql injection free, even when db code 2 does not call sanitizeInput at all. CMIIW. thanks
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Whats Your Security Regimen ?

Post by Mordred »

global_erp_solution wrote:

Code: Select all

function insertMe($data){
    $query='SELECT * from TABLE1 where ' . sanitizeInput($data);
    //do something with the query
}
No. This is still vulnerable to SQL injection (even though it's not real code but just a sketch). Escaping is necessary, but not sufficient in preventing injection.
Read the article on SQLi in my sig for details.
global_erp_solution
Forum Commoner
Posts: 25
Joined: Sun Jul 08, 2012 6:47 am

Re: Whats Your Security Regimen ?

Post by global_erp_solution »

what about DB code 2? is it free of SQL injection? even without calling sanitizeInput at all?
also, I put critical files outside web root, is there any way at all to access those critical files via browser? or is it safe already?
Post Reply