PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Fri Dec 19, 2014 2:13 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Sun Jun 17, 2012 1:40 pm 
Offline
Forum Contributor

Joined: Sat Nov 19, 2011 10:32 am
Posts: 194
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 ?


Top
 Profile  
 
PostPosted: Sun Jun 17, 2012 4:34 pm 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 12722
Location: New York, NY, US
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)


Top
 Profile  
 
PostPosted: Sun Jun 17, 2012 4:57 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 5701
Location: WA, USA
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


Top
 Profile  
 
PostPosted: Sun Jun 17, 2012 6:06 pm 
Offline
Forum Contributor

Joined: Sat Nov 19, 2011 10:32 am
Posts: 194
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.


Top
 Profile  
 
PostPosted: Sun Jun 17, 2012 6:57 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 5701
Location: WA, USA
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.


Top
 Profile  
 
PostPosted: Sun Jun 17, 2012 7:13 pm 
Offline
Forum Contributor

Joined: Sat Nov 19, 2011 10:32 am
Posts: 194
I indeed have a user table with username field. :)

Thanks for your clarifications. All points taken


Top
 Profile  
 
PostPosted: Mon Jun 18, 2012 5:34 am 
Offline
Moderator
User avatar

Joined: Tue Nov 09, 2010 3:39 pm
Posts: 3889
Location: Montreal, Canada
Live24x7 wrote:
3. mysql_real_escape_string() to avoid SQL injections

Prepared statements with bound parameters to avoid injection.

_________________
Stay on top of upgrades.
Supported PHP versions
No longer supported versions


Top
 Profile  
 
PostPosted: Tue Jun 19, 2012 3:35 pm 
Offline
DevNet Master
User avatar

Joined: Wed Jun 27, 2007 9:44 am
Posts: 4294
Location: Sofia, Bulgaria
https://www.owasp.org/index.php/PHP_Sec ... heat_Sheet

_________________
Image
http://openfmi.net/projects/flattc/ Linux is better :)


Top
 Profile  
 
PostPosted: Mon Jul 09, 2012 4:19 am 
Offline
Forum Commoner

Joined: Sun Jul 08, 2012 6:47 am
Posts: 25
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 :
Syntax: [ Download ] [ Hide ]
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


Top
 Profile  
 
PostPosted: Mon Jul 09, 2012 5:04 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 5701
Location: WA, USA
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 :
Syntax: [ Download ] [ Hide ]
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).


Top
 Profile  
 
PostPosted: Mon Jul 09, 2012 6:30 am 
Offline
Forum Commoner

Joined: Sun Jul 08, 2012 6:47 am
Posts: 25
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


Top
 Profile  
 
PostPosted: Mon Jul 09, 2012 9:28 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 5701
Location: WA, USA
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.


Top
 Profile  
 
PostPosted: Tue Jul 10, 2012 3:07 am 
Offline
Forum Commoner

Joined: Sun Jul 08, 2012 6:47 am
Posts: 25
for the sql injection part:

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

Syntax: [ Download ] [ Hide ]
function sanitizeInput($dataToBeSanitized){
    return mysql_real_escape_string($dataToBeSanitized);
}
 


and the DB code 1:
Syntax: [ Download ] [ Hide ]
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:
Syntax: [ Download ] [ Hide ]
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


Top
 Profile  
 
PostPosted: Tue Jul 10, 2012 5:25 am 
Offline
DevNet Resident
User avatar

Joined: Sun Sep 03, 2006 5:19 am
Posts: 1579
Location: Sofia, Bulgaria
global_erp_solution wrote:
Syntax: [ Download ] [ Hide ]
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.


Top
 Profile  
 
PostPosted: Wed Jul 11, 2012 12:37 am 
Offline
Forum Commoner

Joined: Sun Jul 08, 2012 6:47 am
Posts: 25
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?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group