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.
Related
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.
I have not santized user inputs and data comming from url etc what i did is i encoded each and every thing in database as base64 even id of tables primary keys.. is it enough to fight against vulnerabilities ?
No, it's not.
All you'll manage to do with that (apart from wasted CPU and space in your database) is to store unsafe data. If done correctly you've protected yourself against SQL injection. But that's all. As soon as you decode the data, you're back with all the problems of unsanitized data.
So unless you're planning to never do anything with what you've stored, you're not safe.
What is the vulnerability you are protecting against? as stated by Mat, you'd be immune to SQL injection but that would be all.
In addition, it is worth noting that base_64 encoding has no security value beyond the removal of SQL injection and it is obvious to any viewer that your data is base_64 encoded, so it is easy to crack.
Might I suggest you read the work of OWASP before you go any further. Some of it is a little dry but most is valuable pre-reading for any web developer. If you just make sure you are covered for their top 10, that will do for a start.
To give some pointers for reading:
DO think about your data. Anything sensitive should be protected. The truly paranoid might consider AES encryption but frankly unless you are storing health, financial or military data, that is probably overkill. Keep your key secret - anyone who can download your db can probably download your key. There are ways to prevent this BTW but your question suggests you are not quite at that level yet.
Where you can, don't encrypt keys as it prevents indexing, and leave trivial data unencrypted. but DO make sure that unencrypted data cannot be used to draw significant conclusions about encrypted data.
DO store passwords as salted hashes. At least if your db is compromised, the hacker will not be able to attack your users' other accounts (they WILL use the same password...)
DON'T use email addresses as usernames AND password resets. It's either/or
DON'T DIY security solutions. AES is good enough for anything short of CIA after all.
DO obfuscate your keys in HTML - there are lots of simple obfuscators on the net.
Do check for an authenticated session for EVERY page that accesses your DB ESPECIALLY AJAX scripts.
DON'T rely on client side authentication - that only stops the stupid. Malicious people can get round it very easily.
FINALLY-
DO use prepared statements for ALL user input.
Sorry to go on a bit, but these issues come up in one form or another every day in this forum and it is worth having a bit of a repeat of them.
Once you are doing/not doing everything on the above list, you will be immune to most serious problems though still far from secure. I have deliberately not fully explained any of the methods as you will learn a huge amount about application security by googling them and reading around a bit.
have fun...
EDIT to answer the comment below.
There is nothing inherently wrong with using base_64 encoding as a means to beat SQL injection. It is completely reliable as base_64 encoding does not include any characters that can upset the sql.
There are a few reasons not to though:
-It is very data intensive, taking a lot more space to store your data.
-It makes searching through your data very inefficient.
-It makes it hard for you to read your data but not harder for an attacker.
-It provides no effective password protection (use a salted hash for these please).
echo base64_encode("Abcde")."<BR>".base64_encode("cd");
demonstrates the search and size issues effectively - you can't use LIKE or wildcards effectively without an extra instruction - WHERE from_base64(field) LIKE '%cd%' will work if you have mysql 5.6.1 or above.
If it suits your particular needs to do it this way, then well and good but I put it to you that you are not learning to do this properly. If you use prepared statements instead, you can store your data efficiently, indexably, scalably, searchably, securely, human-readably and easily-debuggably.
What you are doing will work well enough for a very small site but not for anything larger.
I've searched around and found a way to do exactly this. But I'm hesitant because I occasionally read that its a "security risk". Unfortunately, nobody ever elaborates on why. I, personally, can't think of any security risk that wouldn't involve an attacker already having permissions they shouldn't. The MySQL/PHP servers are running on the same machine. so there's no public requests between the MySQL and PHP.
The PHP script triggered, will make an API call to a web service on a third-party CRM/ESP that keeps a simplified version of certain tables on a their server. Our marketing team could then log into the CRM's GUI and send emails, gather information, and plan marketing campaigns without the need to bother the dev team.
The tables on this server do not mirror ours, they contain only information they would need. The reason I want to use triggers is to keep their information as up-to-date as possible and have that logic in one place, instead of scattered throughout the project.
UPDATE:
I always sanitize/validate any Forms that touch MySQL. I never store PHP in my tables. I never use FTP (SFTP using a .pem instead of a password).
The script that will be executing will be a single file I created that won't change which is going through the same framework I'm using (zend). The only variables passed to the script will be the row's id (which will be validated as an INT).
I'm thinking of not doing this because of performance. And making PHP execute Asynchronously is possible, but difficult and not worth my time to implement. But I'm still curious, Other than the performance penalty, how would the security concerns be any different than say a web service? I mean you definitely have to sanitize/validate just like you would a web service, so given that, what concerns would there be?
There are different ways your app can be compromised, such as SQL injection, a sniffed FTP password, or a vulnerability in the code itself. It is generally a good idea to keep these things as localized as possible to prevent a breach in one area from cascading.
For example, say that you are storing sensitive data in your database. Typically, you would encrypt this data somehow, using a salt and key that is not stored in the database itself. Then, if your database is compromised by SQL injection, the attackers may cause damage, but they will not be able to steal the sensitive information. However, if you are executing PHP stored as text in your database, the attacker will certainly realize this and update it to execute his code, from whence he can figure out how you are encrypting the sensitive data and unencrypt it.
In short, SQL injection is very common (even if you are following best practices, nobody says the intern who walks in next year will) and it is therefore not safe to execute code stored in a database.
EDIT: after reading your link more closely, I need to restate some things. I don't see a particular security risk in this, but this seems to really contravene the separation of data and logic. Further, mysql is not async and there is no way that this can possibly scale under load...
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'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.