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.
Related
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
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.
i started learning a bit about mysql and while i was reading i was thinking that the security vulnerabilities on mysql are pretty immense and can't be well covered if someone doesn't truly understand pretty much everything about mysql.
if i have a website that will store not a very big volume of information, would it be bad to store it in .php files?
what are the implications and vulnerabilities of this?
it seems to me that the risk is far smaller because if the .php file doesn't have an echo statement, if you try to access it all you get is a blank page, and if you are unable to 'send code' by user input and send files to the website it should be secure as far as the website is concerned (obviously that if the server itself is hacked the attacker pretty much has the control of everything but that's not the point on this matter)
update to the question.
it seems that what i've written above isn't producing the kind of answers that i expect and so i will try to simplify.
what i'm looking for here is why are databases more secure than flat files without bias because most people i've read stuff about on this subject will just say databases are more secure but can't say why. yes they're faster and it's easier to manipulate the data especially if it's complex or with multiple users and there is a lot of info. about that and it's easy to understand why.
the fact is that when i started reading about mysql a few days ago i saw that if your php is compromised most likely so are the databases so writing good secure php code is probably the first and most important line of defense to your mysql databases.
if your php is uncompromised so is the information you stored in php files so if you write good secure php, the security of plain php files will be good.
having databases also makes you use php functions that usually you wouldn't use and some of them possess real security holes that have to be "patched up" so writing good secure php code to work with databases is more complex than writing equally secure code to work with plain files.
also when you have apache/php/mysql installed you have 3 things that may have entry points for hackers if they're not correctly configured and maintained, if you cut mysql loose you only have 2, you won't have to bother with sql injection for example because with no databases that's impossible to happen, you may inject all sql you want but you will get nothing.
so for managing small amounts of data, plain files seem to me like a secure, a bit more complicated to work with the data, slower but not relevant considering that it's a small amount of data we are talking about.
why may these deductions be wrong is the information i'm looking for with this.
Apples and oranges.
You can go to a drag race with a Hummer and complete the race but you will surely be in last compared to a Bugatti. Take a Bugatti off-road and it will definitely fall behind the Hummer.
PHP is a server side scripting language. Data storage and retrieval is not the primary consideration in PHP.
mySQL is a relational database management system. It's design is 100% purposed for data storage, retrieval, and security.
What's your plan for data storage and retrieval in PHP? It seems like will have to do a lot of unnecessary work re-inventing the wheel to achieve this. Why would you?
Without understanding what security concerns you are specifically worried about in mySQL there isn't much more to add.
Edit: An article calling out the general differences.
These two points will cover most security issues:
1)Learn PDO and the prepared statement protocol. This will take care of most if not all SQL injection issues. Do not send raw SQL to a database.
2)Sanitize all your GET and POST data that comes into PHP. This will take care of most XSS.
Many frameworks in other languages do this for you, but the PHP newbie will just use bare PHP and open himself up to all kinds of attacks. That is why PHP is "unsafe."
Read up on security, and try to implement some of the pointers that you feel are important. No language, framework, platform, etc is 100% secure. Just like everything else in life, you take as many steps as possible to minimize the risk.
I'm a relative newbie to PHP and just making my way through the W3Schools tut.
The tut makes a big point of saying you must always filter external data (i.e. cookies, form data etc).
I'm writing a fairly simple system that talks with a third party Joomla extension. It's at a prototype stage where I'm just wanting to demonstrate the functionality in a minimum viable product.
Basically, I'd like to know... what's the worst that could happen in I don't filter content. Are we talking 'I might get a bunch of spam', or 'a good hacker could get root server access'?
Have hunted around online, but would love any of your experience / insight on the matter!
If you don't filter the input data, your site will probably be prone to an SQL injection attack. Check this site. It contains a humorous comic, quite famous too. It depicts the problem of SQL injection quite clearly :).
A good hacker could theoretically get root access.
If you don't filter content that goes into database queries, the database will run whatever was put into the query.
In that case, the hacker might be able to download a database full of usernames and passwords. Which you certainly don't want. Especially if your root passwords are in there because you've used the same password twice. Or they might just delete your database altogether. I've read reports of that happening.
I just wanted to know what are some basic PHP security techniques I should use when creating a web page that accepts articles?
I'm fairly new to PHP and was wondering what will hold the fort down until I'm a security expert?
There are two fronts to consider when accepting user-generated text that will later be displayed.
First off, you need to protect your database from injection attacks. There's a simple PHP function for this: mysql_real_escape_string() will usually suffice to protect your database from injection when passing this string in to store as a field value.
From there, you have to be careful about your display, as a user who is allowed to upload HTML code can do nasty things to other users when that code gets displayed. If you're doing plaintext articles, you can simply htmlspecialchars() the resulting text. (you'll also probably want to convert newlines to tags.) If you're using a formatting solution, such as the Markdown engine used on this site, those solutions will usually provide HTML sanitization as a function of the engine, but be sure to read the documentation and make sure.
Oh, make sure you're also verifying your GET/POST variables used to submit the articles. That goes without saying, and the verification performed is going to need to be tailored to what your site is doing with its logic.
This is to broad, maybe you should try to narrow it a bit.
What kind of security?
For passwords?
Do you want to restrict some stuff?
SQL Injection?
HTML Injection?
Cross domain security?
Well, as mentioned in the other answers, there are a number of different fronts in which your PHP scripts can be compromised.
Here are just a couple:
SQL Injection
Cross site scripting
There are a number of ways to deal with each. Here are some things to look at:
Suhosin
eval()
There is a lot to know, and you should start as soon as you can.
For one, if you accept articles (and probably use a WYSIWYG and are accepting HTML), use something to parse the content and strip out things that could leave you vulnerable to XSS and the like.
An example is HTML Purifier.
It might be wise to start by using a framework like Drupal or CakePHP. That way you can both learn from the way they've implemented security and take advantage of the fact that it's already been done. The learning curve is steep enough without having to roll your own authentication mechanisms etc.
maybe two tips could help you get more secure websites
create two users in your database, read only account to make only selects and counts, and write account when you have to do updates, inserts or deletes.
when you have to insert into database or delete, sanitize inputs, use mysql prepared statements or assert values that arrive via post or get this way :
if(!empty($_GET["integer_like_id_value"]){
$integer_id_value = (int)$_GET["integer_like_id_value"];
}else{
// that stuff seems not to be legit, die application, log error ? whatever
die();
}
Top 7 PHP Security Blunders
When your project is ready for public usage, it is generally a good idea to set error_reporting(0);
It won't provide more security, but it makes it lot harder (usually) for bad guys to find possible security problems with your site.