How can I have a password inside PHP code and guarantee that no one viewing the page in the browser can retrieve it?
Is: <?php $password = 'password' ?> enough? Is there a better, more secure way of doing this?
That depends on the type of passwords you want to store.
If you want to store passwords to compare against, e.g. having an $users array, then hashing is the way to go. sha1, md5 or any other flavor (here’s an overview)
Adding a salt accounts for additional security, because the same password will not result in the same hash
Update: password_hash uses a salted, strong one-way hash with multiple rounds.
If you want to store passwords to connect to other resources like a database: you’re safest if you store your passwords outside your document root, i.e. not reachable by browsers. If that's not possible, you can use an .htaccess file to deny all requests from outside
Your PHP code will (baring configuration errors) be processed on the server. Nothing inside the <?php ?>; blocks will ever be visible on the browser. You should ensure that your deployment server will not show syntax errors to the client - i.e. the error reporting is set to something not including E_PARSE, lest a hasty edit of live code (admit it, we all do them :) leak some information.
Edit: The point about storing them in a file outside the document root to avoid exposure if your PHP configuration breaks is certainly valid. When I used PHP, I kept a config.inc file outside of htdocs that was required at runtime, and exported configuration specific variables (i.e. passwords).
Let's say your password is "iamanuisance". Here's how to store the password in your code. Just slip this in your header somewhere.
//calculate the answer to the universe
${p()}=implode(null,array(chr(0150+floor(rand(define(chr(ord('i')+16),'m'),
2*define(chr(0x58),1)-0.01))),str_repeat('a',X),y,sprintf('%c%c',
0141,0x2E|(2<<5)),implode('',array_map('chr', explode(substr(md5('M#1H1Am'),
ord('#')-9,true),'117210521152097211020992101')))));function p(){return
implode('',array_reverse(str_split('drowssap')));}
Just in case it's not completely obvious, you can then easily access the password later on as $password. Cheers! :P
There are noumerous ways of doing this. However, people will not be able to view the password you stored (as plain text) in a PHP file, since PHP is a server side language which means that, as long as you don't print it out to the browser, it will remain invisible.
So it's 'safe'.
If you can retrieve the password within PHP, then it is retrievable...
The only thing that you can do is to move you password to a "protected" location.
Most hosting companies will offer a separate location where you can place your DB files etc, and this location will not be accessible via the browser. You should store passwords there.
But they are still on your server, and when someone gets access to your box, then he has your password. (He gets to your PHP that has the way to decode it, and he has access to the protected file -> he can read it)
So there is no such thing as a "safe password"
The only option YOU have is to not STORE PASSWORDS for your users etc... I get mad if I subscribe to a service, and they offer to send me my password via email in case I forget it. They store it in a "retrievable way", and that's no something you should do.
That's where all the hashing and salting comes in. You want to veryfy that someone can access a resource. So you hash + salt the password, and store that in the DB for the USER who want to access the service, and when the user wants to authenticate you apply the same algorithm to create the hash and compare those.
Basic, probably not 100% watertight but enough for general purposes:
hash the password (use salt for added security) using your favorite algorithm, and store the hash (and the salt). Compare salted & hashed input with stored data to check a password.
Store the password encrypted. For example, take the output of:
sha1("secretpassword");
...and put it in your code. Even better, put it in your database or in a file outside of the web server's directory tree.
PHP code blocks cannot be retrieved by clients unless they output something. Observe:
<?php
if($password=="abcd")
echo "OK";
else
echo "Wrong.";
?>
User can get either OK or Wrong nothing else.
I generally do not trust raw PHP code for passwords for services. Write a simple PHP extension to release the password. This ensures that the working set is password free, and it makes it an extra step for a compromised machine to grant access to the hacker to the service.
As suggested, store the password sha1, salted and peppered
function hashedPassword($plainPassword) {
$salt = '1238765&';
$pepper = 'anythingelse';
return sha1($salt . sha1($plainPassword . $pepper));
}
and then compare the two values
if ($stored === hashedPassword('my password')) {
...
}
And if you can't store your hashed passwords outside of the server root, remember to instruct apache to forbid the access to that file, in your .htaccess file:
<Files passwords.config.ini>
Order Deny,Allow
Deny from all
</Files>
The best way is to store password above your root directory. If you decide to have password in php file then no body would able to view because php files are excuted in the server. But if the server does not support php then those files will be delivered as text files and any one can see the password.
Related
I'm editing web pages directly using ajax, and php with simple html dom. I dont see the point of using a database when I can do without. However, my hands go cold with fright when I think of storing admin password for the app on the webserver using serialize even though it is above htdocs, it is encrypted and I am using an anti brute force script.
I dont want to use a database just for one password but is it secure enough?
I look forward to your thoughts...
A file with the correct chmod permissions is just as secure as a database storage in this instance.
Think about it: the mysql database is actually stored in binary files on your server's filesystem. If a malicious user gains access to your server they have the same access to the binary database files as any other file, including your serialized and encrypted data in a text file.
As long as this text file isn't in a directory that's publicly accessible via the web server it's no less secure. Of course, if someone gets root access you're pretty much foobar'd either way.
What you should never do is store clear text passwords. md5() is (just) okay. sha1() has now emerged as a better option for encrypting this type of data.
Database doesn't let you have your password more secure than in file system, because in case your server gets hacked, your database password gets hacked too, which means that the admin password will be revealed in any case
If this login is and will be for you only, it's quite easier to store your password in your code/ in a file. But you have to encrypt your password to prevent hackerkiddies from reading this file and login. Please don't forget right chmods on the file ;)
As long as you aren't storing the plain-text password in the file, I don't see a problem with keeping a password hash in the actual php file.
Example using SHA1:
if(sha1($_POST['password']) == "8cb2237d0679ca88db6464eac60da96345513964") {
//success
} else {
//failure
}
you should store your "Hash" somewhere secure ( the key you're generating a password with) . it doesnt matter where you store that password if someone can get to the "hash / key", they can get to your passwords. the nice thing about a database is that it's most likely going to be easier to traverse your directory structure and find a file than it is to connect to your database, discover your table structure, then discover the values stored in a field in the database..
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 want to build a simple single user login "library" in PHP, but I'm facing the following dilemma: how should I store username and password if I'm not using a database?
A simple plain text file could be easily read and then the password could be easily decripted so that's not an option.
If I create a php file with just
<?php
$Username= "username";
$Password= "password";
?>
then no one should be able to read it and I could simply include this file where I need it, but I'm not really sure you can't find a better way to do this!
So what's, in your opinion, the best solution to this problem (and why)?
Thanks
A plain text file is an option, and it's the simplest solution here. Simply hash the password (with salt). It is not reliably decryptable.
You can use PHP's md5 or sha1 hash functions for this.
You can store it in a file and use a SHA1/SHA2 hash, that way it can't be decrypted.
user:<sha1hash>
user:<sha1hash>
...
If you need multiple accounts, a plain text file would be easier than using a PHP source file. I think you're worried about people requesting the file through their browser though?
Check if your web host has some kind of directory that isn't publically accessible, for example a parent directory of where the actual web content is. PHP will usually be able to read and write there, but it won't be accessible through the web.
File permissions and/or .htaccess files (Apache) may help you if there is no such directory you have access to.
I suggest you use the crypt function to store the password (hash), rather than storing plain passwords. This is a separate issue from where you are storing them though :)
You can use a plain text file with a hash or crypt function.
It's reliable but not really flexible if you have a lot of users.
You can also use SQLite which is a database but which isn't a server and which is stored in a simple file.
It's a nice compromise if you can't install a SQL server but want to store a lot users and have more flexibility.
Depending on what you want to do, an .htaccess could be a good solution.
It's already secure but as the plain text solution it's not rely flexible. But it's built-in almost all Apache configuration.
What is the purpose of having a username if there's only ever one user?
Might as well just manage permissions using .htaccess...
(This started out as a comment to Daniel DiPaolo, in response to Mokuchan.)
If you want to store a password (no matter the location), you use the following scheme:
$hashedPassword = $salt . hash( $salt . $password);
The storage location of the hashed password should be safe. Be it in a database or in a file with the proper permissions set.
If a file, your 'record' for the user bob with password secret would look something like this (using BCrypt Hash):
bob:$2a$05$tlk4M8WSpVkO7ER6QGxcwuY91MrBCQn.TCDZ5eOM1iz2sCChtR62K
There is no way for anyone to 'decrypt' the password. That's the whole point of using a Hashing algorithm: it is non-reversible.
You state that:
There are some tools that try to decrypt md5 and sha1, and at least in some cases they seem to work
As hashing algorithms are non-reversible, this is not possible. (There is no 'decrypt' option)
My best guess is that you are referring to a tool that looked up a hash from a precomputed table and it returned a valid input string, likely to be your password.
These tables are called rainbow tables. They can be defeated by A) using a random salt and B) using a strong hashing algorithm (BCrypt hash or SHA2-family hash for example)
Regarding improper hashing algorithms: MD5 and SHA1 are considered cryptographically broken. In other words: you should not be using them any more.
For a discussion on this, see: https://stackoverflow.com/questions/2768248/is-md5-really-that-bad
Ditto to all those saying you can encrypt the password.
Also, don't put the file in the document tree. Put the file somewhere else. Your PHP program should still be able to read it by specifying an absolute path or a relative path that goes ".." however many levels to work up the hierarchy and then to where the file is. (In Java apps, there's a WEB-INF directory that is convenient for storing this sort of stuff. I don't think there's anything like that in PHP -- it's been a while since I've done any PHPing -- but you can always just put the file completely outside your application's directory hierarchy.)
Do not reinvent the wheel, use this one http://pear.php.net/manual/en/package.fileformats.file-passwd.file-passwd-unix.php
The best way to do is
$password_hash = hash("sha256", "iamawesome");
// 4aa4029d0d0265c566c934de4f5e0a36496c59c54b6df8a72d9c52bdf0c1a0e8
$user_entered = hash("sha256", $_POST['password']);
return ($user_entered == $password_from_db);
hashin will secure your password..
detailed article : http://wblinks.com/notes/storing-passwords-the-wrong-better-and-even-better-way
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.
As per question, is it safe to store passwords on php pages such as
$password = 'pa$$w0rd';
If the users can't see it, it's safe, right?
EDIT:
Some people actually suggested using hash, however, there would be a problem with database server connection password, wouldn't it?
The short answer is both No, and It Depends.
It's almost never a good idea to store passwords in plain text, especially in a web accessible location, if for no other reason than a simple server misconfiguration or an echo in the wrong place could expose it to the world.
If you MUST store a password, (which is possible) you could try to store it outside the webroot, eg
/var/www/public_html/ Put your codez here
/var/www/includes/ Put your passwords here
Even better than that would be to have the system that you need the password for (eg a database wrapper ) return an object already instantiated. so rather than asking for $databasepassword you ask for a PDO object, and store your database classes outside the webroot.
The It Depends comes from what attack vectors would cause someone to have access to that password text, and would it require them to be already inside your filesystem, if so, you're probably screwed anyway.
Also, if its the password to your supa-secrit subscriber content, meh, all you've lost is some subscription fees, if its your database, you may have a problem, if it's your online banking details, um good for you.
How valuable is the thing the password is protecting?
Depending on how you define safe, any approach has its positive and negative aspects.
If you really want to store a password in your source, it might be a good idea to do something of the sort:
File: config.php
if( ! defined('IN_CODE') ) die( 'Hacking attempt' );
define( 'PASSWORD_HASH', '098f6bcd4621d373cade4e832627b4f6' );
File: index.php
define( 'IN_CODE', '1' );
include( 'passwd.php' );
if( md5($password) == PASSWORD_HASH )
...
Plain-text is never a good idea, always store a hash of the password you want to store.
Furthermore, try to seperate defines like this from your main sourcefile.
Usually they can't see it. But if something bad happens on server there's a big possibility that server will return your php code in plain text w/o executing it and therefore user will see all source of that file and also your password.
I would store password somewhere where it's not on document root (Cannot be open in browser) and then open that file with php and read the content (password). Or if you have multiple passwords/users, I'd store them in database for fast access.
If you want to use the file method directory layout should look something like this (depneds on server)
/public_html/index.php
/password.txt
$myFile = $_SERVER['DOCUMENT_ROOT'] + "/../password.txt";
if file_exists($myFile) {
$fh = fopen($myFile, 'r');
$password = fgets($fh);
fclose($fh);
} else die("No password file");
if ($user_input == $password) {
...... Authentication succeeded ..........
......your relatively protected code .....
} else die("Wrong password");
If you want even more security instead of storing password as text in that text file. Sore it's hash and then when you want to compare it with user input generate hash from the user input and compare it to the password's hash you loaded from text file
sha1($user_input) == $password_from_txt
As long as your PHP installation works as it should, this is no less secure than any other method. I would prefer named constant (define) over variable. Additionally you might consider storing a hash of the password, instead of plain password. This prevents stealing your passwords even if the site is compromised.
As for being bad practice, it depends. If you need to store just one password, this approach is ok. Storing them outside document root may give a false feeling of extra security; the document root is no more absolute than any other setting of the server.
Unless the site itself is compromised and now so are all the things those passwords grant access to (your DB, perhaps?).
It depends how you define 'safe'.
You are right in that a general user won't see it.
However it is definitely a bad practice; if your site is compromised, what else will these passwords give access to? I'd say at a bare minimum you should be storing a hash of the password, not the plaintext.
Sometimes it just has to be f.e. for a mail application where you can only login with the plain password and not with a hash. And if your application doesn't have security issues it should not affect you.
I belive that most of the times plain text password would be database password as MySQL, for exmaple, won't accept hash for authentication.
As mentioned before best solution is to keep PHP config file with password outside the webroot.
If you are worried that someone may see your password while you viewing the file you can simply make it unreadable for human using base64 funciton.
See this post for details and even small utility for Windows, Linux and Mac that makes it easier.