I have a website which is a front end to a MySQL database. This data is also exposed via a web service (fur use in Android application).
Currently I am maintaining the data via PHPMyAdmin but this is cumbersome and not that "pretty".
I want to create an /admin module where I log in (against values in a PHP Varialbe or a MySQL table) and once logged in I can edit,delete,add data.
Questions:
Is it acceptable in terms of security to compare entered credentials against static variables? There will only be one user so I feel like it is overhead to create a table for members.
Any guidelines on going down this route?
I don't see any reason why you couldn't do it this way, assuming you will always have just the one user. The main consideration would be if someone somehow got a look at your code, they would see the stored password. So, you could store it using password_hash to generate a one way hash, and then verify it with password_verify. Here's how I might do it:
Using password_hash(), generate a hash:
// copy the hash output, then delete this code
echo password_hash("thepassword", PASSWORD_DEFAULT);
Then, in your code, store the hash:
// paste hash here
$passwordKey = '$2y$10$j33UPA7gNxSOBsXQcyquLOZRuO6X8k8hZOb1RA79iN8gLlqp9eIPO';
Then run password_verify() to check the user input:
if (password_verify($userInput, $passwordKey))
echo "correct";
else echo "incorrect";
Demo: http://3v4l.org/PknTI
consider looking at this manual for encryption methods with php. My gut instinct is to make a user table, or at least a table with just the encrypted password in it, rather than just checking the variable against a value.
That being said, if you don't think anyone will really even consider trying to fool around with the system and get past it, you probably don't need to be this cautious. I've built a few front-ends as well as back-ends to communicate somewhat friendly with a database, and I've never experienced a considerable amount pressure on the security.
Hope this helps, if you have any questions about how I've designed the ones I've made, feel free to email me at spencer#codeshrub.com
If phpmyadmin is installed at your server localy, than it is NOT securely at all
You can use any MySQL client that supports ssh connection. E.g. Sequel Pro for Mac or HeidiSQL for WIN.
Also, you can use basic HTTP Authentication for you admin script. But, since it's very simple it's not protect you from bruteforce or password leaking, etc.
Anyway, if you prefer security you need to make your own authentication in PHP, You can use this package for example. It is simple and has many security features
Related
I am building my own game panel and it required the user to introduce into the database the user and password of their linux server. This will allow the game panel manage their servers. My problem now is this:
When the user introduces his linux user and password it is stored in plain text into database and then it is retrieved in the PHP script. However, if the database ever gets breached the hackers will be able to breach their servers as well and I want to avoid that at all costs.
At the moment I am using register and login system in which I implemented password_hash($password, PASSWORD_BCRYPT) and password_verify. I tried to use the method to my problem but it required user input in order to match the stored password with it.
All I need is to store an user and password into database in the most secure what that when a hacker manages to breach my database all the data there will be useless to him.
I am a newbie PHP web developer working with Javascript and BASH. I am still a newbie in these to fields as well. So if you can offer my newbie-friendly answers I would more than thankful to you. (as my first question was answered within hours I am positive I will find a solution to this one as well)
I'm getting informed on data encryption in these days as well, especially to implement the "Privacy by design" concept legally required by the GDPR (The EU General Data Protection Regulation).
Using PHP and MySQL there are two main ways you can encrypt your data, getting it ready to be stored into your DB:
Using MySQL functions AES_ENCRYPT / AES_DECRYPT
Using OpenSSL functions in PHP, in particular openssl_encrypt and openssl_decrypt (it provides, among others, an AES-256-CBC encryption). To know how to use it, you can have a look directly at the examples in the functions' documentation or check out this answer on StackExchange.
What I suggest you, if you have the opportunity, is to use Laravel and its encrypter, which provides all you need to easy encrypt your data using OpenSSL with AES-256-CBC.
I am working on an Android app that deals with some slightly sensitive information (Names, Usernames, Passwords, Badge number, etc)... As far as code work goes, I know how to connect to a MySQL database with PHP and pull information from it via JSON. I am just worried about the security of doing this. I know there are plenty of Android and iPhone apps that currently implement login systems, but I was curious as to how secure those logins are.
Does anyone know where I can find some information on creating a secure connection to a database with PHP and MySQL for my login system through an Android app? I know nothing is completely impenetrable, but I want to make sure the security of my app is as tight as possible.
As always, I am still getting used to StackOverflow, so if I was not clear or this question has already been answered, let me know!
If you're rolling your own authentication code, it's really hard to say how secure it is. Often people get this horribly wrong and the code has the opposite effect: Instead of securing the site it exposes several severe holes that can be used to hijack it and download arbitrary data.
A development framework like Laravel comes with an authentication system built-in. If there's vulnerabilities in that code, which is reviewed by the community, there's usually an advisory posted so you'll know and can patch as necessary.
If you follow best practices, you should be fine. JSON via PHP or any other language is a good way to go if you want to keep things simple and secure.
Its really hard to gain 100% , but you can use some techniques like
SSL
Session for each user
something like verification code sent through SMS
Encryption data before sent over API calls etc
It is incredibly insecure to connect to a remote db from an app. Think of it like connecting to a database from javascript in your browser, because it is the same level of security.
As an important aside,
slightly sensitive information (Names, Usernames, Passwords, Badge number, etc).
Passwords are not slightly sensitive, they are critically sensitive. I'm not sure if you are implying that passwords are being stored in a reversible format, but they should be hashed.
Anyway, to your main question, instead of connecting directly to a database from the client-side device, you will want to create an API that provides limited access. You would write this in the form of a web service, using some server-side programming. From there, you'll simply use an API key/roles based on the current logged in user. This is the secure/proper way to design this system. You do not want to put db credentials in an app, unless they are for a local db on the phone.
To extend what Gray said, you can pass the JSON data through the URL that you're shipping to the web service that's providing the front end to your DB. There are a couple of other examples that you can find here to start. As pointed out, it's a really bad idea to have direct DB access. Even with a front end, you'll want to ensure that you're doing lots of data checking in the front end. Don't pass direct SQL queries! They're too easy to hack. SQL injection continues to be one of the most successful attacker techniques.
You might consider a Mobile Backend as a Service provider, like Kii, Kumulos, Kinvey, Kony (not sure why they all start with K...), or built.io. They'll cost you money, but save you headaches.
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'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.
I have a PHP script that runs as a CGI program and the HTTP Authenticate header gets eaten and spit out. So I would like to implement some kind of FORM based authentication. As an added constraint, there is no database so no session data can be stored.
I am very open to having a master username and password. I just need to protect the application from an intruder who doesn't know these credentials.
So how would you implement this?
Cookies?
I could present the form and if it validates, I can send back a cookie that is a hash of the IP address come secret code. Then I can prevent pages from rendering unless the thing decrypts correctly. But I have no idea how to implement that in PHP.
A few ways you could do this.
htaccess -- have your webserver handle securing the pages in question (not exactly cgi form based though).
Use cookies and some sort of hashing algorithm (md5 is good enough) to store the passwords in a flat file where each line in the file is username:passwordhash. Make sure to salt your hashes for extra security vs rainbow tables. (This method is a bit naive... be very careful with security if you go this route)
use something like a sqlite database just to handle authentication. Sqlite is compact and simple enough that it may still meet your needs even if you don't want a big db backend.
Theoretically, you could also store session data in a flat file, even if you can't have a database.
Do you really need a form? No matter what you do, you're limited by the username and password being known. If they know that, they get your magic cookie that lets them. You want to prevent them seeing the pages if they don't know the secret, and basic authorization does that, is easy to set up, and doesn't require a lot of work on your part.
Do you really need to see the Authorization header if the web server takes care of the access control for you?
Also, if you're providing the application to a known list of people (rather than the public), you can provide web-server-based access on other factors, such as incoming IP address, client certificates, and many other things that are a matter of configuration rather than programming. If you explained your security constraints, we might be able to offer a better solution.
Good luck, :)
If you're currently using Authenticate, then you may already have an htpasswd file. If you would like to continue using that file, but switch to using FORM based authentication rather than via the Authenticate header, you can use a PHP script to use the same htpasswd file and use sessions to maintain the authentication status.
A quick Google search for php htpasswd reveals this page with a PHP function to check credentials against an htpasswd. You could integrate it (assuming you have sessions set to autostart) with some code like this:
// At the top of your 'private' page(s):
if($_SESSION['authenticated'] !== TRUE) {
header('Location: /login.php');
die();
}
// the target of the POST form from login.php
if(http_authenticate($_POST['username'], $_POST['password']))
$_SESSION['authenticated'] = TRUE;
... About salt, add the username in your hash salt will prevent someone who knows your salt and have access to your password file to write a rainbow table and crack number of your users's password.