I would like to create a PHP extension to do some specific crystallographic functionality.
Is it possible for an attacker to disassemble (or somehow xdebug) the extension to find out how it works?
Could the attacker find out constants or variables which are set inside of the extension (for inst. a password, salt, etc...)?
UPDATE
The idea was:
I want to store some data in DB encrypted, I also want to make sure that every user has his own password/salt, so nobody could access data of somebody else in case the attacker would find a hole in the access control.
I could to the encryption in PHP. But if somebody gains the access to the web directory, he can easily see how I do that... he can just take the data and decrypt it at home.
I could make the extension. The attacker would need gain access to the whole filesystem to get the extension. I could limit the extension use just for the server's IP address (so the attacker would not be able to take the data out from the server that easily). Wouldn't it be more secure? Is there some other way how to do it better?
Is it possible for an attacker to disassemble the extension to find out how it works
Yes. This is pretty trivial to get code back out. The variable names will be stripped (assuming it's a non-debug build), but it's 100% possible to get the code.
Could the attacker find out constants or variables which are set inside of the extension (for inst. a password, salt, etc...)?
Yes, these are always stored in the file in plain text. In fact, there's a unix command strings which will extract it for you.
A better solution would be to look at the problem you're trying to solve, figure out what attack vectors you want to protect against, and then mitigating them. There is no magic solution to any of it.
Related
I am using PHP with a singleton PDO to access the database, and it it obviously need MySQL's username and password.
As we all should know, the username and password should not be stored in a public directory.
I can therefore do something like require 'some_path/my_secrets.php'; which sets a bunch of variables, but then these variables are defined potentially globally which is not a good idea (granted, not globally when using a singleton, but still). Okay, I can only require the secret file within some function, but that is a lot to remember...
Is there a better way to make private data available to the PHP script? Also, any other steps I should be taking? Thank you
Most systems I know have a .htaccess protected include file. Inside you define a config array and done. Maybe not the most secure way of doing it but that is many shops, CRMs and other web services do it.
I had the same problem and initially
DB passwords were stored in an include file within the includes directory (ie to prevent a incidental PHP code display directly from the web files)
then came another idea, a bit more complex but still pretty doable
Make a C program that owns the DB data encoded and delivers the data from a system call. The source code (that includes the encoded passwords) is owned somewhere safe. The C code has to perform some checks to ensure the call is made from PHP etc...
but this is pretty expensive - C is fast, but loading all the time the passwords through system is expensive. Therefore adding APC to the game makes the whole thing easier and faster
during the first request, load the DB data into APC permanent variables - thus the data is in memory and more difficult to obtain from outside. Typically the algorithm is
algo
Check if APC variables are set
If yes use them
If no load them from C program, only once
APC documentation
Another idea, using php-fpm for instance is to set an environment variable within the fpm configuration (readable only by root) that contains the passwords
Finally, you could also create your own PHP extension that provides the data from the C code (extensions are usually written in C). This is some extension documentation.
This is not the definitive answer in how to prevent passwords stealing, but at least it would make more difficult for the hacker to determine the passwords - and would require also more knowledge.
Your solution is fine.
Most of the suggested solutions are just exaggerated as although they may higher the level of security a bit they are not worth the additional effort.
Because the security should not only rely on the secrecy of the password. At best, even if the password get’s revealed, its knowledge is worthless for an attacker as he cannot use it.
This means, use a MySQL user dedicated to your application with permissions following the principle of least privilege and only allow the access to the database from that application’s web server (see MySQL Access Privilege System).
First off, I would say, unless your PHP app needs it, restrict the permissions of the app's database account as much as possible (e.g.: read access on appropriate tables, perhaps write access as few as possible). If your app needs admin access to create tables, etc., that's a whole 'nother can of worms.
Secondly, as ring0 suggests, don't store the database password in plain text. I would recommend using a hashing API to store a hash of your password, such as this: https://gist.github.com/nikic/3707231. And of course, the hash might be best stored in some other 3rd place (at least a separate file). If your users are trustworthy, and you can figure out a way, you could have the hash be computed from the user's log-in information, but that might require separate entries in your password file for each user (because each hashed DB password will be different).
There is never a foolproof way, and I'm not a security expert, but I know plain text is always bad for storing passwords, so I think this is a step in the right direction.
I have a php page (just one page - consist of security information and validation) that I want to create an encryption on it, actually in this case I don't have any DB to save data, so I must put the username and password on itself!
the question is how can I encrypt or hide username and pass in this file and how to check the validation for login ?
this page must be very secure, till if it lost, they can't access it?
I check the md5 method for username & Password but how can I hide it on the file :(
please help me because it's very important to me!
Thanks a lot ...
Hard-coding the password in the PHP file is not per se a huge security issue, as someone would need to access the PHP file anyway to read it: if someone gained access to your PHP files you would have a much bigger problem than your lost password.
However, avoid:
storing the password in clear text, save an hash instead.
storing the password in JS files, as the source of JS files is accessible by the client
There are different types of hashes, I would suggest not to use MD5, especially if your password is not very complex. Sites like this hold databases of MD5 hashes, so your hash could easily be cracked.
Use something a bit more secure, like SHA256.
NOTE: obviously whoever owns the server has the physical access to your files and DB, but if you stored the hash you should be fine. If you are really concerned about the possibility that whoever owns the server has a look through your "secure" stuff, you shouldn't be using a shared server as a start.
Store username/password in a variable/array inside the PHP file. Only people with access to your server can see the username then.
Storing the information in a file with a strange filename together with a hash algorithm + salt is also a possibility.
Using .htaccess to make sure that no one can actually visit it increases the security further.
Don't use this to protect something important as it's not really a good way to do it.
I have a PHP file i made that basically give me passwords to all my users. I want to be the only one able to view the contents and see the page. Whats the best way doing it?
Password protection? Requiring a special cookie that only I have?
Give me some ideas..
I'd recommend that you stop storing passwords and store the hash of the password instead. Even you shouldn't really know your users' passwords.
What you're doing isn't even authentication or authorization. At best it's identification. If you're hell-bent-for-leather on doing it, what Chacha102 said, plus you'll also want to chgrp it and chmod it so that only the internet user and your user can view it.
If you want to be able to see if via a browser, try these:
Look into WWW Basic Authentication, which will basically have the browser prompt you for a username and password.
http://www.htaccesstools.com/htaccess-authentication/
http://eregie.premier-ministre.gouv.fr/manual/howto/auth.html
If you have a static IP address, you could make sure that only your IP address can see the page:
if($_SERVER['REMOTE_ADDR'] != '192.168.1.1')
{
die();
}
If it isn't suppose to be seen by a browser, The BEST Solution would be to put the file above the DocumentRoot. AKA:
If your index.php file is at /Path/To/Root/Public_HTML put the file in /Path/To/Root
Don't store your users passwords in plaintext, hash them in the database.
Since I'm assuming you need the functionality of logging in as a user, I would suggest creating a script that let's administrator accounts (you can identify that however you want) log in as any user.
If you're storing all the data in a location that's under the wwwroot, then you risk downloading of the file, whether by bad configuration of by security vulnerability. It is also possible that this solution includes hard coding of users and passwords, which makes password rotation more difficult. And if users can change values in the file, you've got to be extremely careful that they can't inject PHP code into the password file, or they'll be able to take over your application. And the ability of an administrator to see cleartext passwords is considered a bad practice, and should be avoided.
The modern best practice is to not do it that way, if at all possible. Store the data in a location from where the web server does not normally allow direct downloads (such as outside wwwroot or in a database where you've protected against SQL injection issues), implement an authentication and authorization scheme, and rely on that scheme to control who's allowed to do what.
Check out www.owasp.org to get more details - it's a great starting point.
I have created a class file database.php which handles all the sql queries and connecting to database. I store username and password for the database in a variable (which is easily seen if one gains access to the php file).
I want to encrypt that username and password so that even after having that php file one is not able to have an idea of the original username and password.
Please help me as I am in need of some idea desperately.
Thanks
This can hardly be done. You need the password in a decryptable form to send it to the database. Any such form will in some way be readable by a person who gains access to the .php file.
The common sense approach is to keep the configuration files outside the we broot as a basic security measure, and prevent outside attacks through properly securing the server. Hundreds of thousands of web sites run that way, without additionally encrypting their sensitive data in the way you describe.
I'd hate to break it for you, but if someone has access to your source files for your site then it's already game over. They will be able to insert code into them to just scrape the data needed, or more likely get the code to install a trojan onto your visitors computers. It's best that you spend the time and engineering effort locking down your servers and development machines so that a perpetrator can't get in. Also having a good disaster recovery plan is a necessity.
If someone has access to your source, then they have all of the means necessary to connect to the database, regardless of how you store your password. After all, the PHP interpreter eventually needs to know what the actual password is, and anyone who can see the source can do exactly what the PHP interpreter would, thus acquiring the password.
Instead, you need to find a way to control who has access to your source.
Sorry I had misinterpreted the question to begin with..
If you are using a username and password for your script to access the DB, then obviously you need to store this somewhere to begin with (in your script).
The only way I can think of would be to obfuscate the password in your source and do some manipulation to get the correct value. But this just seems like overkill, as if someone has access to the source already then more than likely they can figure the rest out..
EDIT:
Why not store the username/password in a local file on the server, then only give read access to PHP? At least that way it is not directly viewable in your source code.
There's no way of encrypting something so that only MySQL can decrypt it. You need to provide MySQL with that plain-text password sooner or later.
Idea
Set the file permissions on database.php as low as possible. If you have this:
rw-rw-r-- gaurav gaurav database.php
Then maybe set it like this (assuming your php-processes are running under www-data)
r-------- www-data www-data database.php
I assume you are distributing the code somehow, or that you don't trust your own host environment.
There are ways of encrypting PHP source but they have varying levels of complexity and cost. Some require additional (decryption) software to be installed on the host server, which may or may not be an option that you can have.
Have a look at this article for some further info on a number of PHP encryption tools.
If (and only if) your intention is to stop showing the username+password to people who have access to the source, it could be done. It's not too convenient however, and consists of these steps:
One-off:
put your username and password into a strongly-encrypted file (e.g. AES with a long,strong key) and set its permissions accordingly
On every boot:
on server start, decrypt the file, manually entering the file's password, and use some long-running process as a temporary storage
now that you have the username+password stored in memory, erase the decrypted version of the file.
In your scripts:
request the username+password from your temp storage
connect to database
remove the username+pw from your script's variables
Note: all this means that the password cannot be recovered by looking at the source code. Those who can modify and run scripts on your server are in the same position as before - "request password, print it out", instead of just "print it out". Another disadvantage is that you now have to enter the decryption password on every server restart.
When storing a password you ALWAYS use one-way hashing, preferably SHA-256 (because MD5 isn't secure) to store the password. And when you want to compare the password, simply SHA-256 hash the attempted password and see if the hashes are the same.
Encrypted passwords are simply not secure, if there's a way to get the raw text password out of the garble, your security is flawed.
PS: And yes any website that can email you your password is flawed.
One of solution can be used is to hash some stable environment parameters, like sha1($_SERVER['HTTP_HOST'].$_SERVER['...']) and use the hash as db password.
I'm going to be implementing a PHP/mySQL setup to store credit card information.
It seems like AES_ENCRYPT/AES_DECRYPT is the way to go,
but I'm still confused on one point:
How do I keep the encryption key secure?
Hardwiring it into my PHP scripts (which will live on the same server as the db) seems like a major security hole.
What's the "best practice" solution here?
You should think long and hard about whether you REALLY need to keep the CC#. If you don't have a great reason, DON'T! Every other week you hear about some company being compromised and CC#'s being stolen. All these companies made a fatal flaw - they kept too much information. Keep the CC# until the transaction clears. After that, delete it.
As far as securing the server, the best course of action is to secure the hardware and use the internal system socket to MySQL, and make sure to block any network access to the MySQL server. Make sure you're using both your system permissions and the MySQL permissions to allow as little access as needed. For some scripts, you might consider write-only authentication. There's really no encryption method that will be foolproof (as you will always need to decrypt, and thus must store the key). This is not to say you shouldn't - you can store your key in one location and if you detect system compromise you can destroy the file and render the data useless.
MySQL, there is six easy steps you can do to secure your sensitive data.
Step 1: Remove wildcards in the grant tables
Step 2: Require the use of secure passwords
Note: Use the MySQL “--secure-auth” option to prevent the use of older, less secure MySQL password formats.
Step 3: Check the permissions of configuration files
Step 4: Encrypt client-server transmissions
Step 5: Disable remote access
Step 6: Actively monitor the MySQL access log
Security Tools
I agree, but don't the cc if you don't need too. But if you really have too, make sure the file that have it is not accessible on the web. You can write a binary that would return the key. This way it's not store in clear text. But if your server is compromise it's still easy to get it.
the security you need depends on your application. for example, if the only time the cc# will be used is when the user is logged in (thin online store type scenario), then you can encrypt the cc# with the a hash of the user's plain-text password, a per-user salt, and a dedicated cc# salt. do not store this value permanently.
since you're not storing this value, the only time you can get this value is when the user enters their password to log in. just make sure you have good session expiration and garbage collection policies in place.
if this situation does not apply to you, please describe your situation in more detail so we can provide a more appropriate answer.
Put your database files outside computer lets say external hdd and keep it at safe place. Works only if you can develop this project at only place where this external drive is placed :)
Or you can at least protect those files using file system encryption tools like
https://itsfoss.com/password-protect-folder-linux/
In case of production environment I agree with Kyle Cronin.