...

View Full Version : PHP Coding/Security Guidelines Checklist



chump2877
09-11-2009, 03:36 AM
PHP Coding Guidelines Checklist



1. In general…
a. I’m assuming here that the programmer is not also the server administrator, and that the server admin more or less knows how to configure LAMP correctly and securely by default


i. Of course, if necessary, a programmer can override most PHP settings in a custom php.ini file located in the web root

b. Use an MVC framework


i. I use CakePHP (http://cakephp.org/). The framework itself goes a long way to ensure fundamentally sound and secure coding practices.
2. Incoming data…
a. Sanitize and validate all data contained in $_GET, $_POST, $_COOKIE, and $_REQUEST before programmatically manipulating the data.

b. SQL Injection


i. Definition: Code injection technique that exploits a security vulnerability occurring in the database layer of an application. The vulnerability is present when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and thereby unexpectedly executed.


ii. Prevention: mysql_real_escape_string (http://php.net/mysql_real_escape_string)($string)

c. Cross Site Scripting (XSS)


i. Definition: Security vulnerability typically found in web applications that allows code injection by malicious web users into the web pages viewed by other users. Examples of such code include client-side scripts (i.e., JavaScript).


ii. Prevention: htmlentities (http://php.net/htmlentities)(strip_tags (http://php.net/strip_tags)($string))
3. Browser requests…
a. Cross Site Request Forgery (CSRF)


i. Definition: Type of malicious exploit of a website whereby unauthorized commands are transmitted from a user that the website trusts. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser.


ii. Prevention: Generate a unique “token”, typically when a browser session starts. Pass the token in all POST and GET requests. Following the POST/GET action, check for the existence of the token in the session and then confirm the token sent by POST/GET is identical to the token stored in the session. (An MVC framework like CakePHP makes this relatively easy to implement uniformly throughout your application.)
4. Sessions…
a. Destroy session data when killing a session


i. After a session is complete (”logout”), destroy its data and don’t just clear the cookie (a malicious user could otherwise just re-instate the cookie and use the session again). Unset all indexes in $_SESSION by assigning it to an empty array.

b. Store sessions as files above the web root or in a database


i. The default path for saving sessions on the server can be hijacked -- especially in a shared hosting environment.
5. Passwords…
a. Enforce the selection of strong passwords


i. Require numbers, symbols, upper and lowercase letters in passwords


ii. Password length should be around 12 to 14 characters

b. Hash and Salt all passwords


i. Use at least sha1 (http://php.net/sha1)() to hash your passwords (do not use md5 (http://php.net/md5)()) The hash (http://php.net/hash)() function provides some additional hash options including sha256. Add an “application-specific” salt to passwords before hashing them. Store the salt in a file above the web root.
6. In a custom php.ini located in web root…
a. Disable register_globals (http://php.net/security.globals)


i. Prevention: register_globals = Off

b. Disable magic quotes (http://php.net/security.magicquotes)


i. Prevention: magic_quotes_gpc = Off

c. Disable error reporting (http://php.net/security.errors)


i. Prevention: display_errors = Off

d. Enable error logging and save log file to a directory above web root


i. Prevention: log_errors = On; ignore_repeated_errors = On; html_errors = Off; error_log = /path/above/webroot/logs/php_error_log

e. Store session data inside a directory above web root


i. Prevention: session.save_path = /path/above/webroot/sessions
7. In a .htaccess file located in web root…
a. Disable directory listings site-wide


i. Prevention: Options -Indexes
8. Valuable/Sensitive files…
a. Prevent unauthorized access/downloads by storing such files above the web root


i. This includes site administration/members-only sections and site/database configuration files!!

b. Use an intermediary script to serve the files inline or as an attachment


c. Keep your scripts(WordPress, PHPMyAdmin, etc.) updated.

d.Only allow access to PHPMyAdmin when you are using it. This prevents people from being able to use zero-day exploits on your install.

9. Uploaded files…
a. Validate file name stored in $_FILES before using it for any kind of data manipulation

b. Be aware that the provided mime type can be spoofed or otherwise wrong

c. Move all user-uploaded files to a directory above web root!!!

d. Don’t execute/serve uploaded files with include()

e. Try to not serve files with content types of “application/octet-stream,” “application/unknown,” or “plain/text”
10. Misc…
a. All “utility” files/programs in the web root created and used by the developer during the development of a site/application, that are not intended or required to be accessed by future site users, or otherwise pose some kind of security risk, should be removed when the site goes live.



i. For example, this includes a “phpinfo.php” file (a files that prints the results of phpinfo (http://php.net/phpinfo)()), database utility scripts, etc.

Zangeel
09-11-2009, 07:49 AM
I <3 google, even if it is evil!!!!

http://www.jemjabella.co.uk/articles/php-security-checklist

chump2877
09-11-2009, 09:01 AM
Thanks Zangeel, that security "checklist" is OK, but it is very basic and doesn't include everything that I'm looking for (from memory -- of course, if I remembered everything, I would just make my own list!)...and, also, I was a little unclear in what I was looking for: I'm looking for "advanced" security guidelines as well as "advanced" coding guidelines in general ("advanced" including basic as well as more sophisticated measures)...and the list need not expound on every technique -- just list them (makes it easier to audit my applications in true checklist fashion), and include everything. You might almost describe the checklist as a coding guidelines (including security guidelines) "cheat sheet"...

Again, I wish I had made a copy of what I was using earlier, but alas it appears to be gone forever. It was a tool that I used to audit my work against a loooong list of general coding and security guidelines, covering the gamut of proper coding, site/app deployment, and security techniques. I'd even be willing to pay for something like this if I could find what I was looking for...

Zangeel
09-11-2009, 11:46 AM
Well google has a ton of sites under keywords "Php Security Checklist", such as http://aymanh.com/checklist-for-securing-php-configuration

You're not going to find the "ultimate" guide unfortunately because as technology improves so does the methods to get by security. But you've already got the most important ones down, sanitization of database inputs, cross site scripting. A few others i'd note are things like using "includes" for example if you include pages based on $_GET, make sure to have "safe" words in an array, or scan your directories to make sure what theyre requesting in the $_GET variable is OK and not harmful.

Making sure directories and files are safe and secure (i.e. not all CHMOD'd to 777) if you're proficient at php, then you'll also know the weakspots of your codes.

Security is a question that can be added to infinity. Maybe others can post what they think is the most secure way of doing things, and what they've learned is good practice. Those were just a few off the top of my head.

chump2877
09-11-2009, 12:18 PM
Security can be added to inifinity, but it behooves programmers to be very thorough (anal, even) about the security of their apps -- especially for those who do it for a living. If a customer's web site or app is breached, your customer loses money and you know who they are going to blame.

Ideally, you shouldn't be using GET to collect and manipulate user data at all. POST only. Especially in administrative sections of web sites.

The link you provided looks promising for php.ini configuration. I'll read through it later. I also found this (http://sk89q.therisenrealm.com/2009/08/definitive-php-security-checklist/), but haven't read through it yet. I need something really thorough, that is recent, and then I can add to the list as new coding practices evolve.

The company I worked for "had" an "ultimate guide" for general coding practices, as a part of their intranet wiki, and unbelievably they did not back up the wiki content. It was a valuable resource for me that may be hard to replace.

As an aside: It might be a good idea for a coding forum such as this one to create a sticky post in the PHP board dedicated to documenting good coding practices, in list format. Then the post can be continually updated over time to accomodate new techniques. That would be a great resource, and similar to the company wiki I was referring to at my old job.

technica
09-11-2009, 01:30 PM
what about SQL Injections?

you should put it into the list too if you have not updated it yet.

Zangeel
09-11-2009, 08:35 PM
I disagree, $_GET is a powerful tool in the PHP aresenal, I'm a big fan of the MVC framework, with basically pulls all pages through one central index.php file, then using mod rewrite we can wok in different looking URLs, the method can be very safe if you know what you're doing with it, maybe using $_REQUEST is a bad idea because of variable overriding, since it also reads POST and COOKIE data. I wouldn't be quick to knock off a major way of doing things.

Coyote6
09-11-2009, 08:53 PM
I disagree, $_GET is a powerful tool in the PHP aresenal, I'm a big fan of the MVC framework, with basically pulls all pages through one central index.php file, then using mod rewrite we can wok in different looking URLs, the method can be very safe if you know what you're doing with it, maybe using $_REQUEST is a bad idea because of variable overriding, since it also reads POST and COOKIE data. I wouldn't be quick to knock off a major way of doing things.

Definitely do not discredit the $_GET statement. That is one of the best ways to make your website user friendly and get you ranked higher in search engines. Just be sure to validate every little piece of data you take from there. I think what Chump maybe suggesting is that you do not post any highly secure data in the $_GET statement. Ex. usernames and passwords

But take a search page for instance. If you only use a $_POST statement the user will have to resubmit the form every time they want to search for the same thing. Say a person needs to check once a day to see if any new products match his search.

Instead of resubmitting $_POST data every time, if the $_GET statement was used he could retrieve them by just bookmarking the url.

http://store.com/search.php?products=bears&color=red

And especially user and search engine friendly if mod_write is used:

http://store.com/search/products/bear/color/red

or depending on how it is set up even

http://store.com/search/products/bear/red

but just make sure no one can inject into your url that would affect the database.

chump2877
09-11-2009, 09:58 PM
Regarding GET, sorry for the confusion: I guess I was just warning against using GET to alter stored data. Shouldn't be done. For example, a text link used to add, update, or delete data in a database is not a good idea. For retrieving data (i.e., serving web pages, search functions), GET is often more or less necessary and sufficient as long as its contents are sanitized.

Regarding the security guidelines I was seeking: What I might end up doing here is taking it upon myself to amass an "ultimate" coding checklist, since I can't seem to find everything I need in one place. After I put it all together, or as I put it together, I can incorporate the list into this post. Then I can email a forum admin and request that this post (or a derivation of this post) be made into a sticky. In the future, as new coding techniques emerge (or if I just missed something), any members of this forum can add to the list to keep the list current. Sound like a good idea?

Coyote6
09-11-2009, 10:05 PM
That would be something very useful to all php coders.

:thumbsup:

chump2877
09-12-2009, 03:04 AM
Well I spent a couple of hours and tried to regurgitate and research the concepts that I had in my previous list of PHP coding guidelines. The following is what I came up with. If there are any glaring ommissions, please let me know, and I'll add them to the list. If I goofed something up, I'd like to hear about that, too. I'd like you guys to help me make this list near bulletproof, but practical at the same time (if that makes sense), for developers.

When we get to the point that this thing is "sticky" material, I'll contact a forum admin and see if we can make this a permanent sticky thread for the PHP forum here. So your input regarding the following list is invaluable in helping create a great resource for PHP coders visiting this fourm!

Thanks for the help!!

Moved the list to the first post -Inigoesdr

bacterozoid
09-15-2009, 02:10 PM
A good list. I disagree with two points:

1. Using a framework. This is less of a guideline and more of a recommendation. I think frameworks are bloated and unnecessary and I certainly never plan on using one - but I can still organize my code and implement strong security techniques.

2. Password length. Most users would have trouble remembering a password 12-14 characters long. Yes, it is good to have long passwords, but 8 characters minimum is a little more reasonable.

chump2877
09-15-2009, 03:32 PM
A good list. I disagree with two points:

1. Using a framework. This is less of a guideline and more of a recommendation. I think frameworks are bloated and unnecessary and I certainly never plan on using one - but I can still organize my code and implement strong security techniques.

2. Password length. Most users would have trouble remembering a password 12-14 characters long. Yes, it is good to have long passwords, but 8 characters minimum is a little more reasonable.

1. I acknowledge that using a framework is my recommendation. Still, the fact remains that most professional programmers use some kind of framework to work on their projects. So there must be some merit to them. Rather than expound on the advantages of programming frameworks here myself, I'll provide you with a few links that I quickly found:

Re: CakePHP
http://book.cakephp.org/view/8/What-is-CakePHP-Why-Use-it
http://make-cake.blogspot.com/2007/03/why-use-cakephp.html
http://blemble.com/2009/04/why-use-cake-php/

...and in general:

Rapid Application Development framework
I would Google these keywords and research what all of the fuss is about. In terms of code organization and security, the level of code abstraction in frameworks facilitates more organized and concise code, and effectively automates secure coding techniques (a high degree of security is already assured just by implementing and building on top of the framework's core code).

2. The strength of a password will vary depending on the application and the security required. For example, sites that protect access to sensitive data (i.e., bank/merchant account info, credit card numbers, social security numbers, etc.) obviously warrant stronger passwords than a WordPress blog. In any event, hackers are becoming more and more adept at cracking "weak" passwords. A few links on password strength:

http://en.wikipedia.org/wiki/Password_strength
http://www.microsoft.com/protect/fraud/passwords/create.aspx (All bias against Microsoft aside, they must be doing something right!)
http://www.utexas.edu/its/secure/articles/keep_safe_with_strong_passwords.php

Coyote6
09-15-2009, 07:11 PM
I would recommend not just moving the location of the sessions, but rather storing them in a database and not in a file. No matter where you tell php to store the session in a file it can easily be read if an attacker can place a script on the server and access it through the web. Also make sure to encode all session data so that it cannot easily be read.

But not a bad list to start with. :)

chump2877
09-16-2009, 12:40 AM
Thanks for the great input so far, guys and gals...

As soon as I talk to a forum admin and figure out how to edit the list inside this sticky post (currently I can't), I'll start integrating your ideas into the list...so keep the ideas coming, and eventually I'll get them in there...:)

tomws
03-11-2010, 06:02 PM
Useful read for those who blindly include from the GET string.

http://blogs.sans.org/appsecstreetfighter/2010/03/11/top-25-series-rank-13-php-file-inclusion/

immediate
07-12-2010, 09:32 AM
Sorry for digging up the thread, but I believe here's a much better PHP / web security checklist (http://www.kavoir.com/2010/03/php-security-checklist-for-websites-and-web-applications-bottom-line-for-every-good-php-developers.html).

johnnnn
08-09-2010, 08:25 PM
Jem is a self-proclaimed l33t PHP ninja, and she knows what she's talking about. :P

Keep an eye on her website, she's very helpful on the subject and has many posts concerning it.

My list:

1. Only use error_reporting(E_ALL) while developing, in the release use error_reporting(0)
2. Don't be afraid to ask questions and get help
3. Report ANY errors/warnings
4. Never trust $_SERVER as it can be modified
5. Never trust anybody
6. The PHP manual can be very useful; don't be afraid, it's your friend.
7. Have people test your projects
8. XSS/CSRF etc attacks
9. Sanitize any user input (Forms, Get, Post, etc..)
10. Be especially careful if you use HTML selects, checkboxes, or radio buttons in forms, they can be changed by the user
11. Time and patients can make the biggest difference
12. You should probably make sure you're comfortable with any language you write a script/program in.
13. Lean by example -- look at other people's script.
14. Try to "break" the script on test runs
15. Password encryption
16. Never store sensitive stuff in .inc.php files
17. Place all config files, .ht* files out of your root directory
18. Ask questions: What could I have done differently? Why does X do this? Why does Y do that.

Sorry if the wording of these tips is a bit odd. :P

Kinda posted this in a hurry!

gillianreynolds
05-24-2011, 12:58 PM
To add to this, don't forget that % and _ are both special characters in SQL. It is, however, much safer (harder to make mistakes) to limit input to the characters you want (e.g. [a-zA-Z0-9]) than to hope that you have a complete list of all SQL special characters.

IPTables can limit the number of connections an IP address can make in a given time limit and will simply drop packets until the IP address is below the limit again. You can also limit IP addresses by bandwidth in a given time limit. I'm sure other firewalls will have similar capabilities. Filtering such as this should be done as early as possible in the path through your system as that is where it has already had the least impact on the other users of your system.

I don't have a problem with calling your super user "root" but there is no harm in changing it. You should, however, definitely not allow this user to log in over the network. If the root user can log in over the network then an attacker brute forcing his way in already knows one username (and it's the most powerful user to boot)

Strangely enough, this post is almost not about PHP at all, but security involves the entire system so we shouldn't just focus on PHP anyway.

Thanks for the tips.

XterM
11-23-2011, 10:35 AM
hey, this is nice post.

i have a simple way to prevent sql injection attact. usually, hacker test if sql vulnerable by adding a single or doble quote in input variable. like this:

?id=1' or ?id=1"

so, i remove any quote in all variable. i use str_replace().

i see why hacker do to attack sqlinjection vulnerability. like this:

?id=1+order+by+1--
?id=1+union+select+1,2,3--

so, i remove the +,-,%20,*.

i feel this is just little trick, but this so helpfull to prevent sql injection attact :-)

nani_nisha06
11-13-2012, 05:21 PM
Lovely tut....This type of sticky notes can help beginners like me......:thumbsup:

Regards,
nani

priyankaseo
08-08-2013, 06:10 AM
When developing your own PHP scripts, be aware of security issues. Also view the OWASP Top 10 Security Vulnerabilities. Listed below are some things you can do which will make your web application more secure. For more information, visit the links above.

Always validate user input before using it to do anything in your script. Even form variables such as select boxes need to be validated to ensure that the value chosen is in the original list of values.
Always escape characters such as single or double quotes, backslashes (\), percent symbols, and other characters which could result in an unexpected use of your script.
Take extra precaution when executing commands with user input in them. It is possible for an attacker to inject a malicious command in this way.
When dealing with secure information (such as passwords), be sure to use a good password that will be hard (or better yet, impossible) to guess. Generic passwords such as 'admin', should never be used. The same goes for dictionary words. Secure passwords will be at least 8 characters long, contain at least one (1) numeric digit in them, and do not contain dictionary words. Never store passwords in plain text, always encrypt then with an irreversible encryption algorithm such as MD5.
Stay away from using default filenames, such as putting administrative functionality in the admin/ folder. Generic names such as this are easy targets for hackers to attempt to access.
When instantiating PHP on a page, always use the full <?php and ?> tags. Using shortcut tags such as <? to instantiate php could result in your script being displayed as plain text if the server configuration is changed. :):D:p

jonathanesliot
07-21-2014, 01:40 PM
Great work!
Thanks for sharing this list!

i disagree with one point. I use md5() instead of hash.
If someone is using md5, always with some "strange" salt (a big unique word) what problem will have ????

chump2877
07-22-2014, 07:55 PM
Great work!
Thanks for sharing this list!

i disagree with one point. I use md5() instead of hash.
If someone is using md5, always with some "strange" salt (a big unique word) what problem will have ????

Generally, the degree to which you hash, salt, and protect sensitive data really depends on how sensitive your data is. How much do you stand to lose if this data is hacked or exposed?

These days, md5 is outdated and easily reverse engineered. See this: PHP: Password Hashing - Manual (http://php.net/manual/en/faq.passwords.php#faq.passwords.fasthash). Other, more secure PHP hashing functions exist. For example: PHP: hash - Manual (http://php.net/manual/en/function.hash.php). And this function allows you to see available hashing algorithms: PHP: hash_algos - Manual (http://php.net/manual/en/function.hash-algos.php). So if a function like hash() exists that enables you to pick and choose a more secure hashing algorithm for your application, and it is easily consumed, then why wouldn't you use it? In my opinion, there is no such thing as too much security in web applications. The tradeoff between usability/cost of development and security is negligible when the cost of having your data compromised grows bigger every day! And with computers getting faster and more adept at brute force attacks, there can and should be no shortage of security in your web application.

In general, this is a good read for anyone interested in PHP best practices for hashing and salting data: PHP: Password Hashing - Manual
(http://php.net/manual/en/faq.passwords.php)
For password hashing, this looks to be ideal: http://php.net/manual/en/function.password-hash.php. Looks like the PHP manual endorses the Blowfish algorithm for use with this function.

jonathanesliot
07-23-2014, 12:45 PM
ok...Thanks for your link/info. I'll check and study it thoroughly!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum