making php web application secure - php

to protect my project from attacks (example: SQL injection) im using the below for query
parameter pages(*.php?query=value) :
$id=strip_tags($id);
$id=mysql_real_escape_string($id);
if(is_numeric($id) && strlen($id)<=3) //id are numbers maximum of 3 digits
Apart from this im using client(JavaScript) & server side(php) validations, strip_tags() to filter data as required.
Passwords are encrypted using bcrypt()
All messages are encrypted using mcrypt_ecb()
Pages can only be accessed when isset($_SESSION["id"]) ie logged in.
error_reporting(0);to hide errors.
$_POST instead of $_REQUEST
mysql_real_escape_string(); for every input
actually my project will be used by college and im tensed about the security because backtrack makes it easy to penetrate, so im trying hard to make it safe. (i know it's a vast question, but any kind of help will be very useful) but as a student i want to know what else im missing to make it safe ?

Firstly:
Avoid PHP's MySQL functions like a plague
Use PHP's MySQLi functions instead at the very, very minimum or PDO instead. MySQLi and especially PDO functions, are better security-wise. But, of the two, PDOs are the best deal as they offer you higher abstraction with prepared statements which greatly increases your defense against SQL injection attacks:
Most SQL statements in PHP applications use variable input to
determine the results of the SQL statement. To pass user-supplied
input to an SQL statement safely, prepare a statement using parameter
markers (?) or named variables representing the variable input. When
you execute the prepared statement, you bind input values to the
parameter markers. The database engine ensures that each input value
is treated as a single parameter, preventing SQL injection attacks
against your application. Compared to statements issued through
PDO::exec(), prepared statements offer a performance advantage because
the database management system creates an access plan for each
prepared statement that it can reuse if the statement is reissued
subsequently.
Also, avoid using some of the older depreciated PHP functions.
Next, generally, if you're using PHP or any language that creates dynamic requests, that implies user input on some level, and most oftentimes, a subsequent interaction with the database. Rule 1 of web programming: never, ever under under any circumstances trust user input. At all. Everything entered must be cleaned, validated to avoid security problems. You can do this natively with PHP, but honestly it takes a lot of work and a lot of attention to detail - which of course, expands your development time.
If this is not an academic exercise or one dealing with self-training - try to use a framework if you can - it potentially can save you many headaches later down the road as good frameworks can take care of some of the overhead of dealing with escapes, validation and the like. What that means is that if you go commando and write your own code with no framework: most, if not all of the functionality you'll be implementing would be done for you and chances are - done better in a framework.
Plus, they make PHP development easier, and occasionally, fun. Of course, not all frameworks are created equal, and all frameworks have security issues, too. But, this is something you will have to keep in mind and keep yourself informed at all times, religiously.
If this is an academic exercise, or a self-learning one, read this:
Reasons to NOT use a PHP Framework?
A lot of the top StackOverflow PHP posts and Programmers.StackExchange posts can help you with your journey.
Here's a few to start with:
(This one's more of an overview of what most of these links discuss)
http://www.acunetix.com/websitesecurity/php-security-1/
PHP Session Security
Exploitable PHP functions
What's the best method for sanitizing user input with PHP?
https://stackoverflow.com/questions/325862/what-are-the-most-common-security-mistakes-programmers-make
What common web exploits should I know about?
Read up on security practices in your field. It's ever evolving.
If you're interested in frameworks, here are a few of the popular ones to pique your interest:
Yii
CakePHP
Zend
Symfony
Kohana (highly recommended)
But, either way - good luck!

I'd propose the review OWASP's website for web security related information (or even join OWASP).
This OWASP section provides PHP-related information.

Making a PHP application secure is a pretty complex process. There are lot of thing to think about when you write your application and SQL injection is not the only one threat.
I suggest to refer to the following useful articles:
25 PHP Security Best Practices For Sys Admins
How to secure your php application?
PHP Security Cheat Sheet

Related

Turn Variables into Strings

I am making a login, and will use this for registration, and am allowing symbols and special characters in emails and passwords. I know that this poses a serious threat for hackers with injections. My question is: How might I turn the inputs from fields (ex. 'email', 'password'), into strings and not allow the server to process them as code and commands.
I truly have very little clue as to where to start, but have tried mysqli_escape_string; but, as you most likely know, it is very thin and deprecated. I don't mind researching a little, I would just greatly appreciate a bit of information to get started!
If you really do have no idea where to start, that's not a bad thing! However, I recommend not trying to go create you're own login/registration system unless you do know what to do. Especially if you care about security. This is an extremely easy thing to mess up, even for seasoned programmers. I will be the first to admit, I spent a lot of time rolling my own login/auth modules in PHP, and also spent a lot of time inheriting code where other people implemented their own method, most of the time, improperly.
I recommend learning a web framework. My favorite Web frameworks for PHP are Laravel, and Code Igniter, Laravel being my favorite. You'll find that you'll have a learning curve here as well, but you will find a lot more support for implementing user authentication correctly and securely. For exampe: http://laravel.com/docs/4.2/security
With a framework you could also get lots of helper methods to make DB access fun, easy, and safe. Check out the examples here! You can always use raw sql if you want!, but for your day-to-day CRUD applications, there is no need!
If you still absolutely insist on doing it yourself, though I will warn you against it one final time. I recommend using PDO or MySQLi prepared statements (I prefer PDO).
My guess is that the app isn't too far along since you're still considering how to build login/registration, so you're probably not "stuck" using raw php and doing it all yourself. :)
Use prepared statements when executing mysql queries. (more details here)
Limit input field length when possible (normally a mysql injection queries are long. This prevents execution of altered longer queries even there is a vulnerability made by a mistake)
Give only the permissions needed for mysql users. Wherever you only need the user to read, provide only read permissions.
Encrypt sensitive data like passwords. Use salted password hashing.

PHP - my CMS security

I have my own cms, I'm exploring the security options which I should implement and study.
All my CMS pages are checking of user permissions based on the UserID stored in Session. I was thinking that how much important is it for me to "secure" the forms inside this pages? I mean the users have the opportunity to write SQL statements so if they would want to like use SQL injections it is not really that hard...
So my thinking is to have only the logon page secured + protection against session hijacking, is that correct or am I missing something?
Forms on the front page, query strings etc are also secured.
Thank you for any inside on this.
Securing web apps is a never-ending task. People find vectors to exploit every day (quite literally) through a combination of tools and methods. When building a CMS, you've got to be particularly careful with:
Users being able to log in as someone who they are not
Users being able to remotely inject permanently into a page (especially when combined with above)
Users being able to modify or extract contents of the database they are not supposed to gain access to
All these have to do with form submission, or more generally, userdata entry. It boils down to one simple precept: never ever trust an user.
The first one you have to worry about, and by far the most dangerous, is SQL injection. It's what a lot of companies fall victim to every year, and it is quite in-depth, though most attacks can be prevented by using parametrized queries (TRUE parametrized queries. PDO by default emulates them, there's a config flag to turn on true parametrization). This will effectively do most of the SQL-relevant sanitization for you, leaving the "sensible sanitization" to you (i.e. making sure that a date is actually a date). This protects you from what people tend to call first-order SQL injection - in other words, direct entry.
Second-order is more difficult. It involves storing something in your database that will then get executed in another statement. The CISCO guide has a good idea of how stuff happens.
That's all for SQL to defeat the large majority of script-kiddies.
In terms of content-filtering, you want to use a whitelisting approach rather than a blacklisting one. Remove everything you do not trust or cannot recognize. In terms of HTML, there's a wonderful tool called HTMLPurify that does exactly this.
Also
Don't make the mistake my boss did. Check for the session immediately, not just before rendering the page after the controller has run.

Is there anything I need to worry about besides SQL injections and XSS attacks?

I'm finishing up my first "real" PHP application and I am trying to make sure it is secure. I'm kind of afraid that since I'm not an "expert" PHP programmer that I might be missing something huge, so I would like to give you some information about my application and hopefully you can tell me whether or not that is the case. So here we go:
I'm using a CMS to handle user authentication, so I don't have to
worry about that.
After discovering PDO shortly after starting work
on my application, I ported all of my code over to using prepared
statements with PDO.
I am escaping all form and database data (even stuff I think is safe) which is being output with htmlentities().
My application does use a session variable and cookie variable, but the function of both is very unimportant.
I have designed my form processing functions in such a way that it doesn't matter if the form were somehow altered, or submitted from off-server (i.e. I always check the data submitted to ensure it's valid).
I have done my best to make all error messages and exception messages polite but very obscure.
I'm forcing pages with sensitive information (such as the login page) to be served over https.
When I first starting writing my application, I didn't know about prepared statements, which is kind of a huge deal. Have I missed anything else?
OWASP maintains a list of the Top 10 Most Critical Web Application Security Risks (warning, PDF download). This is from 2010, but I think it still applies, perhaps even moreso now.
Injection and XSS are the top two, but you should certainly be aware of the other 8. If you are using an existing CMS, many of these may already be considered, but the more popular the CMS the more you risk running into vulnerabilities because of black hats trying to find holes in it.
If you are not storing critical data like credit cards, order history, addresses, and even emails, then I wouldn't worry too much about your site being affected as long as you are taking the basic precautionary measures (and it sounds like you are).
If you are concerned about security issues, a good resource is the OWASP - Top 10 Application Security Risks
The most important thing to take care in web applications(specially PHPs') is Data Validation of all the inputs taken from the user which are further saved in your database.
For a secure application, all the transactions should be done on HTTPS. For a secure cookie management Secure and HTTPOnly cookie should be implemented.
Some more points I don't see mentioned yet. Most of these are not related to code - I am not sure if you only wished for things related to code, but I'll mention them anyway.
Backups (user data). should be self-evident
Version control. If you have a big bug, you want to have access to the previous version.
Audit trail, alarms and logging. If you do get into trouble, how will you find out? Are you able to track down what happened? if you know something is wrong but don't fully know what, are you able to diagnoze the issue?
Hosting. Where are you hosting? Do you have adequade bandwidth and monitoring? What happens if you get DOSed? Are you able to block out unwanted traffic?
Caching. Can you change it if needed?
There's always one thing left. Availability :) There are three aspects of security:
Confidentiality (Noone can read what they don't have access to)
Integrity (Noone can change any data what they should have to and you have to be able to detect if it happened even so)
Availability (The data, application whatever has to be available)
You pretty much did a nice job and took care of the first two (credentials, prepared statements, htmlentities...) but none of them will help against a DoS attack. You should be able to detect if someone slaps your site and ban the attackers ip from your server. Although this can be done in PHP (still much better to kick the attacker at the first line of php than let them initialize the framework, database connections etv.) it can be done mre effectively in lower layers (for example: nginx/apache, iptables, snort).
However what you're asking for that usually comes to the matter of risk management. In a real application you're not able to be prepared for all the possible attacks, edge cases etc. What you need to do is classify all the risks by the probability and the impact ( http://www.jiscinfonet.ac.uk/InfoKits/infokit-related-files/Resources/Images/risk-matrix ). With this you can focus on the most important (highest) risks first and probably you can completely ignore the lower bottom part.
SQL Injection and XSS are the most prominent Hacking methods.
You are covered from SQL Injections if you use prepared statements.
Also, if htmlentities() on everywhere you display HTML you should be safe.

How should be test with phpunit for xss + sql injection?

How should be test with phpunit php web application for xss + sql injection?
I thinking to find program that output xss+ other attacks to test my application forms.
This program/service should be all time updated with new xss and other new attacks.
Does such service/program exist, if not how it done today?
Please give some examples if you can.
(I use php 5.3 + zend framework + mysql)
Edit:
I asking about testing!and not prevent techniques that I also know.
Thanks,
Yosef
I don't think you can easily do unit tests for this kind of thing. It would require that your application is written in a way conducive to mocking its component parts and definitely involve a great deal of continuous manual work (making sure there's tests and mocks for everything, testing for the myriad flavors of attacks, etc etc).
The only certain thing is that if you can get some automated tool of broad scope that's always up-to-date, whoever gave it to you didn't charge enough.
The forms of protecting against such attacks are pretty well known and easy to utilize:
Always escape variables in sql, or better yet use prepared statements
If you do not need to accept and preserve HTML input, always htmlspecialchars any variable that goes into HTML (note that there are many formats such as BBCode, MarkDown, Textile etc whose sole purpose is to allow a useful subset of formatting options without opening Pandora's box)
If you absolutely, most certainly need to accept, store and serve HTML data then there's HTMLPurifier that can help -- but do that only as a last resort
Therefore, I 'd say that it's much better value for your time to make sure that you follow these practices/use these tools.
Furthermore, if you funnel all access to these two subsystems (sql and HTML output) through a well-defined part of your application (database access methods that escape all input no matter what; HTML output functions that in the same manner escape input variables and inject them into a provided "HTML template" that you subsequently echo) then it becomes easy to unit test these subsystems. Decent PHP frameworks already do this.
At this point, the only real chance of introducing a vulnerability is by circumverting or misusing these subsystems. In my opinion you are better off spending effort on specifying and following good coding practices that writing unit tests to prevent vulnerabilities in your business logic (unit tests for you sanitization code are of course another thing entirely).
Finally, there are automated SQL injection tools and XSS-related tools that you can use to probe web applications. But unless someone hires you to do penetration testing, it's better to use these as you would use protection in sex: use it, but don't count on it.
I would not write unit tests for XSS or SQL injection detection.
What I would do is:
To prevent XSS, escape all user output with one of:
htmlspecialchars
filter extension (PHP 5.2+)
escape (Zend Framework)
http://htmlpurifier.org/ (External
library)
To prevent SQL Injection, use PDO and placeholders for everything.
ie)
"SELECT * FROM users WHERE uid = $_POST['id']";
becomes
"SELECT * FROM users WHERE uid = ?";
or
"SELECT * FROM users WHERE uid = :id";
Edit
You might also want to try some browser addons such as:
https://addons.mozilla.org/en-US/firefox/addon/hackbar/
https://addons.mozilla.org/en-US/firefox/addon/xss-me/
https://addons.mozilla.org/en-US/firefox/addon/sql-inject-me/
https://addons.mozilla.org/en-US/firefox/addon/access-me/
SQL injections are one of those classes of problems that can only really be found by auditing your code. You should be looking for places where you're dynamically building queries rather than using prepared statements - those are your SQL injection vectors. Change those to prepared statements, and you remove the risk of SQL injection.
Unit testing will help you with logic errors, but won't help you find security problems such as that. The only solutions are vigilance and code reviews/audits.
UPDATE: I almost forgot! You should check out PHP_CodeSniffer for doing automated auditing of your code. It should help you detect at least some instances of where people are doing potentially dangerous and insecure things in code, and you can extend it to detect more problems than the basic install will by default.
Use frameworks like sqlmap
Get the XSS Me add-on for firefox and run it against your pages to test.

What security issues should I look out for in PHP

I just starting out learning PHP, I've been developing web apps in ASP.Net for a long time. I was wondering if there are any PHP specific security mistakes that I should be looking out for.
So, my question is what are the top security tips that every PHP developer should know?
Please keep it to one tip per answer so people can vote up/down effectively.
(In no particular order)
Always check that register globals are OFF
Always check that magic quotes are OFF
Make sure you understand SQL injection attacks
Turn OFF error reporting in production
EDIT: For the "newbies" out there this is a basic why (and since I have time to explain this):
Register globals is an aberration. It's the ultimate security hole ever. For example, if register_globals is on, the url http://www.yourdomain.com/foo.php?isAdmin=1 will declare $isAdmin as a global variable with no code required. I don't know why this "feature" has made it's way to PHP, but the people behind this should have the following tattooed on their forehead: "I invented PHP Register Globals" so we can flee them like pest when we see them!
Magic quotes is another dumb idea that has made it's way to PHP. Basically, when ON PHP will escape quotes automatically (' become \' and " become \") to help with SQL injection attacks. The concept is not bad (help avoid injection attacks), but escaping all GET, POST and COOKIE values make your code so much complex (for example, have to unescape everytime when displaying and data). Plus if one day you switch this setting OFF without doing any change to your code, all your code and/or data is broken and (even more) vulnerable to injection attacks (yes even when ON you are vulnerable).
Your databse data is your most valuable thing on your site. You don't want people to mess with it, so protect yourself and read things about it and code with this in mind.
Again this can lead to security concerns. The error message can give hints to hackes on how your code works. Also these messages don't mean anything to your visitors, so why show them?
Avoid using register_globals.
Warning: This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
Cross Site Scripting (XSS) Wiki, Google
Cross Site Request Forgery (XSRF/CSRF) Wiki, Google (thanks Rook)
Session Fixation Wiki, Google
SQL Injection (SQLi) Wiki, Google
Turn off error messages in Production environments
Keep any "include" code in a directory that is not web-accessible (either deny access or keep it outside of the webroot)
Here's an article I wrote about storing passwords in a secure way, and if you don't feel like taking my word for it, check the links at the bottom.
Also linked in my article, but given its own separate link here, is a paper published by M.I.T. called The DOs and DON'Ts of Client Authentication on the Web [PDF]. While some of its info (recommendation to use MD5 hash, for one) is somewhat out of date simply because of what-we-know-now versus what-we-knew-then, the overall principles are very strong and should be considered.
One of Rooks' links reminded me of another important set of restrictions
Turn off Register Globals (This is the default now, so I hadn't mentioned it before)
When dealing with file uploads, be sure to use is_uploaded_file() to validate that a file was uploaded and move_uploaded_file() instead of copy() or rename().
Read this section of the PHP Manual if you need to know why (and you do).
Since I've now mentioned him twice, check out Rooks's Answer (https://stackoverflow.com/questions/2275771/what-are-the-most-important-safety-precautions-that-a-php-developer-needs-to-know#2275788) as it includes a link to a document which contains (Non-PHP-Specific) information on the most important security concerns (and this therefore probably the right answer).
here is a link of good PHP security programming practices.
http://phpsec.org/
Most of the security issues revolve around user input (naturally) and making sure they don't screw you over. Always make sure you validate your input.
http://htmlfixit.com/cgi-tutes/tutorial_PHP_Security_Issues.php
Always sanitize and validate data passed from the page
In conjunction with #1, always properly escape your output
Always turn display_errors off in production
If using a DB backend use a driver that supports/emulates prepared statements and use without prejudice :-)
don't use "Register Global Variables" and filter user input for xss and injections
Language Vs Programmer. You can write the most serious vulnerability and you won't get a warning or error message. Vulnerabilities can be as simple as adding or removing 2 characters in your code. There are hundreds of different types of vulnerabilities that affect PHP applications. Most people think of XSS and Sql Injection because they are the most popular.
Read the OWASP top 10.
If you're using a mysql database make sure you call mysql_real_escape_string when sending data to the database
There are tons of safety precautions. I can recommend a book Chris Shiflett: PHP and Web Application Security.
http://phpsecurity.org/
Have a look at the Suhosin Hardening Patch, and check out the security vulnerabilities that it addresses.
The PHPSec Guide gives a good overview.
Most of the security issues related to PHP come from using unparsed "outside" (GET/POST/COOKIE) variables. People put that kind of data directly into file paths or sql queries, resulting in file leakage or sql injections.
OWASP provides a lot of insight into security issues that are the biggest problems in applications today. It is nice to see that they have a PHP dedicated page available
http://www.owasp.org/index.php/PHP_Top_5
Always Close you SQL Connection.
Always Release SQL results.
Always Scrub all variables your putting into a database.
When deleteing or dropping from sql use limit 1 just in case.
When developing make sure you have a lock on things to keep the undesirable out. If its open and you know not to load the page right now because it could break something, doesn't mean other people do.
Never use Admin or Root as your server log in name.
Whenever possible, use prepared statements (tutorial. It's almost a must whenever dealing with user input (I say "almost" because there are a few use cases where they don't work), and even when not dealing with input, they keep you in the habit. Not to mention they can lead to better performance, and are a LOT easier, once you get into the swing of things, than piecemeal sanitizing.
Often introductory tutorials don't talk at all about checking data from users. Like all programming environments, never trust the data you get from users. Learn to use functions like is_numeric(), isset(), and mysql_real_escape_string() to protect your system.
There are also features that allow you to access remote files, and other creative things. I'd avoid those until you have a good understand of how and when they work (often they are disabled for security reasons).
Use POST method for data passing from one page to another.
Use trim while getting data like trim($_POST).
Also, use strip_tags for variables before you passing into the queries.
I am suggesting you use any framework link Codeigniter, Laravel, YII, Cake PHP because they maid framework with all securities
I suggest Codeigniter for small projects and Laravel for big projects.
Always use POST and not GET for important Data...

Categories