Is it enough to save all my fields in mysql as base64? - php

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.

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.

Why don't we have a specific database only for authentication and another one for the rest?

I wanted to know why isn't easier and more secure to have one database service, dedicated only to user authentication (withholding usernames and passwords) which would be well secured (inputs well sanitized etc.)
And another database service for all the other data in the website which would be possibly less secured and available for serving web content.
Wouldn't it be a good way to prevent a lot of the SQL injections happening these days?
No. There is a difference between sanitizing inputs and protecting passwords. SQL injection can happen in any query, and allows someone not only to steal, but also to destroy data. This should be prevented at all times.
Regarding usernames and passwords, there are additional measures to take. For one, don't store passwords at all, but always store hashed versions, hashed with a salt. Furthermore, you might put the authentication in a different database or even some authentication service if you like, but like I said, that's extra.
Of course, if you got a big bunch of data that is read-only from a website perspective, you might store that in a different database, or at least make the website connect using a database user that doesn't have any rights to modify the data. That way, the data is better protected against destruction, because errors on the website, SQL injection and even leaking of the username and password will not lead to destruction of the data. But this also goes for both the user credentials as the 'less important' data.
You seem to miss two points :
the rest of your data also should be secure (or else there's no point in securing the application)
you don't store passwords. Never. You only store a hash built from the password, the username (optionally) and a record specific salt. So it's not so important to secure that base, it only is done to prevent impersonation
As there's no reason to secure in a greater manner that part of the DB, just ensure the whole is correctly secured, it's so much easier to manage one DB than two TB. Trying to keep different types of data in different RDBMS and to maintain their coherency is a nightmare.
Lastly, note that this shouldn't change anything regarding to mysql injections. Just don't allow those injections by using prepared statements.
This is a tough quesiton. Indeed you can have two databases one for sensible data, the other for "furnishing".
Let's put it this way: even if you use a database only for "furnishing", what happens if that database get hacked ? Will your users have to see "THIS SITE WAS HACKED" in the section or...? :)
EDIT: What is protection? Protection is when you buy a coffee and you don't want your friend or someone to drink it. Then what if you buy a coffee and a muffin. Would you protect only one ? Would you protect both ? Which one is more important for you ? If you're like me and most people you would say both. What you made me understand by commening is that muffin (users) is more important than something else (furnishing).
Why would you need protection, if you don't care about the coffee ? Probably because you don't really value coffee enough to protect it. Then let me say this: the money you used to buy your coffee were worth when they were still money, but now they're coffee, what's changed apart from their shape ? Nothing.
Now let's get back to our case: if you have a simple database which contains only "furnishing" texts like "TITLE", "DESCRIPTION" etc. Having them lost isn't bad ? Won't you have to go there and fix them ? Won't you have to WORK to get everything pretty ?
Not to speak that most vulnerabilities related to a database might get pretty worse than just losing only ONE database. Having a sql injection issue might get all database destroyed, that's the danger you're trying to avoid. So, it's almost pointless to try to secure a database more than another. Try to secure everything instead, you'll be sure that everywhere you go, nothing could happen.
So you fear a special inmate, and you secure him A LOT, and trascurate that old cell. You look away, the inmate in the old cell is now out of his cell! And worse, he freed the special inmate (and everyone else). That's the kind of security hole a sql injection imply.
I think you need to look deeper into your RDBMS protection layers to get a better picture why they are better in the same instance.
Let's take for example your MySQL database:
an instance is made out of 3 + databases (mysql, information_schema, and all others you create).
so you already have a separate database repo that is handling the auth + user + pass - and that is your MySQL database.
There are ways to develop applications that are hacker free - when working with MySQL most of the coders use open SQL code (inline SQL) - and this is the problem - hackers will take advantage of this! To fix this use stored procedures (encapsulated).
Inside database privileges are a problem as well - lazy developers or stupid DBA will give extra rights for application users. Your idea is redundant from many points of view. More instances will cost you more money, more resources, etc.

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.

PHP and MySQL $_POST Security and md5() hash function

I am creating a information system that will handle financial information, contacts, etc. I am developing the site from complete scratch using object oriented programming (classes, functions, etc). A majority of the data will be from a MySQL database. Users will be able to get and submit data to the database.
I am already using the hash function to encrypt data such as passwords, serial keys. I am also using preg_replace() function for all other data going to the database.
What other security measures do I need to take to insure that submitting and getting data from the database does not compromise security?
md5 is a cryptographic hash function. once hashed, it cannot be "un-hashed" back to the original value (one-way) as opposed to encryption which is two-way (encrypt-decrypt).
for security of your data, consider these scenarios and ways of prevention instead of just encryption:
cross-site request forgeries (CRSF) - prevent using form tokens
SSL connection (the "httpS://") to prevent data interception in transport
hash salting to further protect (but not totally) hashed passwords from dictionary attacks. weak and common passwords are the targets in this case.
hashing is not absolute. there is a limit to how many combinations of letters and numbers in a hash. at some point extremely different strings may have the same hash value. this is known as a collision
hashes are prone to brute-force/dictionary attacks. although hashes are one way, one can create a string-hash dictionary, match the hash and figure out the string behind it.
cross-site scripting (XSS) which can include (but not limited to) cookie stealing, click jacking, etc.
SQL injection - ways to trick your SQL when forms are unsanitized
expendable session ids to track user sessions - which should expire in a given amount of time, hence an auto log-out mechanism.
identify your user! user ip address, browser detection, etc to profile your user. any odd data (like sudden change in IP, location etc.) should be considered within a certain threshold. (facebook has this feature. i once accessed my facebook using a proxy - auto lockdown)
preg_replace() will not do much in terms of security. You should familiarize yourself with some basic security/crypto before doing this work. Also, consider the use of a standard cryptographic library for encrypting/decrypting data instead of arbitrarily using hash or regex functions.
Take a look at this: http://php.net/manual/en/book.openssl.php
First: good for you for giving attention to security issues. It's a big subject and one that many people overlook until it's too late. So, kudos to you for seeking more understanding about best practices. :-)
OWASP is a good resource for understanding web security issues.
Another good resource is the SANS report The Top Cyber Security Risks.
Specifically, Cross-Site Scripting (XSS) and SQL Injection are the top two security risks for most websites. You should read about how to design your code to minimize these risks.
I have also designed a presentation SQL Injection Myths and Fallacies that goes deeper into the nature of this issue and methods of defense.
Read the blog You're Probably Storing Passwords Incorrectly by StackOverflow founder Jeff Atwood.
I also cover SQL injection and password hashing in my book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.
Hope you have good liability insurance if you are using md5 to secure financial information. Read about md5, http://en.wikipedia.org/wiki/MD5, paying close attention to the line
The security of the MD5 hash function is severely compromised.
You are doing it wrong, because:
md5 is considered broken,
preg_replace() will not give you much.
Consider using already developed, tested and secure frameworks (candidates include Zend Framework, Symphony, Kohana, Yii) for your system. You have a long way before you will achieve security at least nearly as good as standard framework's. Also consider using prepared statements instead of preg_replace() and salted sha1 instead of simple md5, if you still want to reinvent the wheel.
Furthermore:
secure your app against such acronyms as XSS, CSRF,
require SSL at all times (for every request, even for images / styles / scripts),
read security newsletters (you will need them if you want to build secure system for financial activities).
As others have pointed out, md5 is broken. Also, a SHA1 hash is very fast to compute which actually makes it worse as a hashing algo. Instead look at bcrypt. Assuming you're using PHP, the http://www.openwall.com/phpass/ is very a nice password to use that handles hashing and salting for you transparently.
Using preg_replace() for escaping data to the database is a very bad idea. Almost all databases include their own sanitization functions, PHP/MySQL is no exception with mysql_real_escape_string().
Some more points (please note none of these are set in stone):
Sanitize all input
Assume that everything the user sends to your server is designed to cause harm. This includes form submissions, but also URL routes, cookie values, server vars, EVERYTHING. Using a framework will often provide some insulation from this, automatically escaping a lot of data for you.
Escape all output
Assume that everything you display on your site is designed to cause harm. XSS and CSRF are amongst the most common techniques for attacking websites. Escape all text that you output to the browser. Look into using nonces to mitigate attacks.
Use TLS/SSL
If you want to protect your users data enroute, get yourself a signed SSL certificate and set it up. This allows visitors to go to https://yoursite.com securely (or at least more securely if they're the kind of person who does internet banking on coffee shop wifi).
Use a framework
Everyone begins by writing their own framework because they know how to do it right, or don't need the extra complexity or whatever reason they come up with. Unless you're writing a super-specific-niche-application for which PHP probably isn't the right answer anyway, use a framework. I prefer http://kohanaframework.org/, but there's a whole range out there from http://codeigniter.com/ through to http://framework.zend.com/. Frameworks handle session encryption, database escaping, input sanitization and more for you, and because they're used by many people the chance of a bug is much less than code that only one person has worked on.
Secure your infrastructure
This one tends to fly by most people, but make sure you take some time to look at the server(s) you're running on. Are you on a shared account? You don't want to be storing financial information on them then (in some countries it's even illegal too). Apply security patches for your OS/software, make sure you haven't left an old upload script lying around, check your file permissions, use SSH with keys and turn off password logins. Attackers are always looking for the easiest way in.
At the end of the day, the only way to stay secure is to sleep with one eye open, totally paranoid. Watch your logs, install Nagios and set-up some alerts, hire a professional to do a security audit. There's no such thing as 100% secure, but knowing that is half the battle.
I am an experienced PHP developer and I want suggest to you to take a look to this project OWASP_Development_Guide. Every web developer should be use it as a bible. It has been very useful for me and I hope it will be the same for you.
Here a brief description of the document:
The Development Guide provides practical guidance and includes J2EE, ASP.NET, and PHP code samples. The Development Guide covers an extensive array of application-level security issues, from SQL injection through modern concerns such as phishing, credit card handling, session fixation, cross-site request forgeries, compliance, and privacy issues.

mysql vulnerabilities. save data in php files or mysql databases

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.

Categories