Connecting to MySQL database from PHP - php

Everything I find on the net tells me to provide the database user and password to connect to the database.
Being paranoid as usual, I don't like this because it means anybody that has the php source can now log into the database and screw with the data. Is this the only way to access the database?
context: http://www.cyberciti.biz/tips/facebook-source-code.html

Yes, it is the only way. Also, as a paranoid you should know that knowledge of login and password is not enough, but you have to login from the right host (which is permitted to log in with this credentials).
Also, as a paranoid, why are you afraid of stealing your sources and not afraid of having vulnerabilities in your code that will allow a hacker to steal data even without login and password? In this case it is better for paranoid to never program at all.

Since PHP will be parsed by the interpreter and only HTML will be output, you need not fear as there will be no way to get hold of the PHP source (guessing that you have set appropriate measures so that the PHP source cannot be downloaded).
Block all traffic to the MySQL server from outside. Only allow localhost to use it.

It's not the only way, but its the way most of the world (like 99.999%) does it, and as far as I can tell, 100% of web programmers.
Consider this: if the password is hardcoded into the source somewhere, why bother? Why not make the account password-less and just limit its access to the web server? Some might say, "oh noooooes!! Don't do that!" But again I ask, what's the difference? What security hole is opened that is not there anyway?
The real security issue is actually protecting yourself from SQL injection. That wide-open account makes you vulnerable if:
1) You have a glitch in code that can be exploited to do something a user is not supposed to do, or
2) They can trick your db server into executing code via SQL injection.
So SQL injection is your big bugaboo to protect against.
There are secondary protections as well. For instance, most people are paranoid about their "users" table that contains users and (unfortunately most of the time) plain text passwords, which are required if you are going to email a user their password.
You can put in a second level of protection on this table (in case they get past your SQL injection protection or find an exploit to make your program do something you thought it would not do) by locking it down so users cannot see it at all or write to it. Then you write two stored procedures, "addUser(username,password)" and "checkPassword(username,password)". This is an example of "security in depth" where you have multiple levels of security around the more sensitive data.

not a lot better but you an specify it in the php.ini
http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-password

You need to provide the connection information somehow, but you can mitigate the risk by setting up your MySQL user to have as limited privileges as possible. So grant read/insert access only where needed, and you can set the user host to only allow connections from 127.0.0.1 too.
There are also commercial obfuscation products like http://www.zend.com/en/products/guard/, which might be of interest. I'm not sure if they include string encryption or not though.

Related

Is it safe to store admin login hardcoded into a php script?

I was thinking something really trivial like:
if ($email == 'mymail#example.com' && pass == '&2r2KdC#i%$$e2r8'){
//do login
}
Was wondering if this open to possible hacks or exploit, but could not think of any. Since it will be just my login it would not make sense to use a whole database to store only that. I'll use database to store users login. I know it sound stupid to have users with less privileges stored securely in a database and admin login hardcoded, but is it really less secure?
It is possible for people to get things from a database without permission, via ways like sql injection if data is not sanitized properly. It is also possible for people to get your php source code, via ways such as having access to your server (e.g. your shell/ftp account), which is quite unlikely assuming that the server is decent enough and you're keeping your credentials for getting into the server safe enough. Do understand that being being a victim of sql injection is a far more likely than people obtaining your php code. (It is also possible that you accidentally did something wrong such as changing the file extension that outputted those lines, the same goes for accidentally writing a wrong query for sql though) There are many more ways things can go wrong of course but here I am just listing out some common problems.
Also, it is worth noting that your database credentials are probably in your php code too, meaning that if they somehow have access to your source code, they most probably can access your database too.
However, I believe the biggest problem is not with where you put the password, it is how you store it. Passwords should not be stored as how they are, instead, they should first be hashed before they're stored, then when you want to check if a password is correct, you hash that password too and check it with the hash you stored. It is very dangerous to simply store unhashed passwords, since if someone somehow has access to them, it poses a huge security threat to your users, some users may use this same passwords for multiple places that someone can have access to all those places (this is very bad you shouldn't do this, but there are people to do this). However, if the passwords are hashed, even if someone somehow has access to all of the hashes, they still won't know the actual passwords.

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.

What security risks are there in using MySQL triggers to execute PHP?

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...

mysql injection damages?

I Just noticed that my mysql_real_escape_string function is not inside a '' in some of my php scripts and it was vulnerable to injections and things like sleep(30) executed on my production site.
I am going the PDO route and implementing the prepared statements after lots of reading here. but this is not implemented yet.
Few questions, I see in my logs that lots of injections where done by people online but I can not see any damages. the user that the site runs to do sql queries has update/select/delete/insert only privileges.
But I am woried things like sleep(30) and what not works and if they did any damages I am not seeing?
Can you tell me where to check for damages or was I safe for at least major damages?
Can they have changed hidden mysql settings or system settings?
By the way, I tried to run latest updates on centos 6+ linux and php.
Thanks
edit:
just to clarify, the database is empty almost and i am not worried about the data being there and the passwords are hashed sh512. so the data inside is not important since this is a new application i am writing. but i am worried if they changed anything on the system or the db i should be worried about. some of the injections i see have java etc but the log is huge and its going to take time to go over it. i also see some schema strings in the injections.
now the question is can they have read my schema info or modified them? why does functions like sleep are working if it is a restricted user? what other functions could they have run?
note i have other DBs in the same MySQL. should i be woried about those?
by '' i mean:
select * from dbname where id=scaped_string
i should have put it in quotes
Checking for damage done to your data is dependent on the kind of data you have in your database. If after careful inspection you don't see anything wrong, then there is probably nothing wrong. If your data is of any decent size, this will be difficult or impossible.
There are many automated bots roaming the internet looking for code vulnerable to SQL injection attacks. Their attempts are probably what you are seeing in your logs. Just because an attempt was made does not necessarily mean an intrusion occurred.
Also keep in mind that you won't necessarily have evidence of data being stolen. The best way to determine this would be to take your server logs and replay them on a copy of your current server, checking to see if you get any data back.
Without any further information, we have to assume the worst case: An attacker is able to read, write, and delete arbitrary data in your database, and possibly even files on your file system, which may lead to compromise of your whole server (e.g. command execution via PHP file, privilege escalation, etc.).
Now let’s have a closer look at the possible impact:
Since PHP’s MySQL extension does not allow multiple statements, so called stacked statement attacks are not possible. So the remaining possibilities depend on the actual statement verb and the context, i.e. the clause inside the statement:
SELECT statement:
Reading any accessible data (e.g. sub-queries, unions, boolean-based blind, etc.)
Reading files (LOAD_FILE())
Writing files (… INTO OUTFILE …)
UPDATE statement:
Obviously updating any accessible data, possibly not just in the current table
Reading any accessible data (e.g. sub-queries, boolean-based blind)
DELETE statement:
Obviously deleting any accessible data, possibly not just from the in the current table
Reading any accessible data (e.g. sub-queries, boolean-based blind)
INSERT statement:
Obviously inserting arbitrary data
Reading any accessible data (e.g. sub-queries)
Some of these may not have a direct impact but may be used to exploit other vulnerabilities. In the end, it depends on the actual vulnerable statement.
As far as I know, there is not hidden mysql setting other than sanitizing your inputs to protect your data from being injected.
You said, you saw lots of injections done by people into the site, and yet you can not see any damage, maybe they were just injecting a plain HTML tags, or trying XXS attacks, because the real mysql injection, can delete your tables, update, reset every data subjected to mysql injection, so if I were you, I would implement PDO right away.
If you have anything like admin panel you should check for webshells and other backdoor-like tools on your server, because attacker could easily read your credentials from appropriate table. And, ofcourse, look for any changes in your pages (look for iframes and suspicious JS code).
Worst case scenario is executing INTO OUTFILE in writeable directory and then accesing it via local include or directly.
But, first of all, before worrying you should consider this as most common automated sql-injection checkers (bots you might say) and if you don't see any damage - mose probably there was no intrusion. But be careful - most intruders nowadays don't look for any visible damage, most probably they will inject some malicious code in your pages (like iframes with their exploits).
So, don't be too paranoid, but still cautious :)

Is using parameterized in just the login script enough?

More of a risk assessment question than technical.
So i have been reading a lot about protecting against SQL Injection. Lets assume i have a large web application that is mostly unprotected and i need to make some improvements to protect against this problem. Read large as lots of SQL interaction using dynamic queries but on few (less than 100 registered users).
My question is... If i have already secured the main login script (the only publicly available user input) using parameterized queries, is it really that necessary to do the same work for the rest of the site? I mean if a potential attacker can't log in, how much other damage can he do?
Assuming of course none of my registered users have malicious intent.
Assuming of course none of my registered users have malicious intent.
Never assume that :) If your users have different rights, one with almost no right could find the way to get admin access... And so on.
Also, protecting against SQL injection does not make your login bulletproof and someone could bruteforce through it or simply have sniffed packets from your trusted users. Make sure you protect your whole application, do not assume that the entry point you planned (login script) is the only one available...
And please use SSL if your website contains or requires any sensitive data from your users.
What makes you sure that none of the legitimate users won't attempt to attack your system?
I'm glad my bank don't think that. Some-one would have emptied my account by now, just by using sql injection attacks.
And even then you should be careful about accidents. If you use parameterised queries, someone using a ' in a value won't cause problems.
It allows type safety in your parameters.
It engenders better programming habits.
It allows execution plan caching. (Without it, every query with a different parameter will look like a completely different query. Not only preventing caching of plans for those queries, but over-filling the cache so plans that really can be re-used get discarded.)
Not only is it more secure, it's more reliable. Other than experimentation and throw-away code, I can think of no project where I would have condoned not using parameterised queries.
Never trust your users!
Even if you do (and nobody can sign up either), there's always the potential of CSRF for instance; an attacker would lead users of that system to a seemingly harmless page with an image. That image would have the following code:
<img src="http://yourserver.com/profile?user_id='; DROP TABLE users" />
My hacking skills are practically zilch, but you can imagine what would happen :)

Categories