I would like to write a setup script for my PHP application, which dose a minimum requirements check, gets the DB credentials, DB prefix and saves them, creates the db tables and so on. Now I would like to know what is the best practise to write and save the DB credentials? Write them as an array into a .php file and? Or into an XML file?
I don't think there is a best practise for this, there are so many ways people use configuration files. Some use PHP arrays, some use XML files, some use INI files, some use JSON files and I'm sure some people create proprietary formats.
What you do want to take in account is, where will you store this file. If it is in the document root, people could request it. XML/INI/JSON files are plain-text and by default, will make it easy for people to 'retrieve' the file contents. PHP will be parsed server side so just returns an empty page.
Ideally you'd store the configuration file outside of the document root, but not all webhosts allow you to do so. So I'd say, if you want to release an application people can install themselves easily, a PHP file might be the easiest way to go.
Write them as an array into a .php file. This satisfies speed (no xml parser and file touching is needed per-page), and security (.php files don't get served as text like your xml would).
I also tend to put the private.php that contains my mysql credentials in the directory above the http root, and load it like require_once("../private.php");
You are asking about setting up the environment, correct? If that is the case, then it depends on the script or build system itself. We are using Ant where such configuration is stored in build.properties. For example:
# database credentials
db.host=localhost
db.user=root
db.pass=root
db.name=db_name
This file is working copy specific and as such is not a part of our VC, however, build.properties.dist is. This way A's local settings don't override B's.
If the question is about something else, please, do tell :)
Related
Issue
In order to connect my PHP code with MySQL database I use PDO way, creating variable, assigning it with new PDO object where arguments contain settings such as server, database, login and password. So in resulting code it could look like this:
$DAcess=new PDO("mysql:host=server;dbname=database","login","password");
I don't feel comfortable having my login data written directly into the code nor do I find it effective in case of possible changes of those data. It was recommended to me to solve this by storing those data in other text file (preferably .INI file) from which it is going to be retrieved anytime I need, for example, having file:
xampp/htdoc/EXERCISE/secret/config.ini
The problem is If any user figures out the location and name of this file, they can easily access it and its content by entering URL/HTTP request into their browser:
server(localhost)/EXERCISE/secret/config.ini
It was adviced to me by the same source the file is supposed to be forbidden from acess by those protocols. So I need to be able to acess the file with my PHP code but disallow any user to acess the directory/file on their own. How to do this?
Possible Solution
I have been roaming these pages and other similar forumses yet all results of my research with keywords such as "forbidden" were about users who lost permission unintentionally. I have also been looking for Google solution, yet Tutorials I have found were referencing to file located somewhere else in my XAMPP version and were about lines of settings not included in this file in my XAMPP version - considering I have downloaded XAMPP from official page, I should be having recent version, thus those tutorials were outdated.
It left me with no other choice but experiment on my own. After a while, I have found directory "forbidden" in directory "htdoc", have played with those files and have ended up with something looking like solution to my issue.
Specifically, I copied .htacess (obviously nameless text file with but extension) and placed its copy into to-be-forbidden directory. I changed nothing in the file but line referencing to login data storing file. I have created my own text file (nameless with but extension .ldatastore) where using copied pattern login:password I have written my own desired login data and made .htacess use this file instead of original htdoc/forbidden/.htpassw.
Since then, it seems it works. Whenever I try to acces those files with my browser on new session (browser closed and opened again, otherwise it doesn't need autentification again), it does not let me browse the directory nor look into its files (neither those which are responsible for those actions such as .htacess or those I created myself such as config.ini) unless I provide valid login data same to those in .ldatastore text file.
So why am I asking this? I feel uncomfortable doing it this way because of several reasons listed below. In case this is the only easy and possible solution, I can live with that, but in case there is much better way you would recommend, I will gladly read that, which is why I am asking for your suggestions. I was also writing this whole text to explain my case fully, provide enough data and express "I have done some research and understanding of the case before asking" so that this would not be by the rules of this page marked as "off-topic".
Reasons Why I Would Prefer Alternative Solution
I feel like it is XAMPP framework dependant. That the whole module making this work is part of the framework's code while .htacess just marks the directories that should be forbidden by this module. That means I am afraid If I would release my project on proper paid server hosting with their own PHP executing software, it wouldn't work everywhere and that this is just XAMPP way to do it. Correct me If I am wrong and this is solution used widely on any PHP executioner.
I was trying to understand the module's documentation located as text file in the "forbidden" directory yet it seems from the documentation this module was developed mainly to make one safe and forbidden server storing secret data accessible then by various different application on different servers rather than just forbidding secret directory (I would leave this directory to be part of my application which is major difference between my usage and by author assumed usage). Correct me If I am wrong and I misunderstood the usage.
Despite the fact I cannot acces the files via browser without login data, my PHP code seems to have no problem acessing the files - I used PHP code to retrieve text from text file that should be forbidden this way and it worked (it echoed the text) with no sign of problems. Well, in the end, I certainly would like to make it work this way yet I expected even PHP code that retrieves the text would need to somehow contain login data to have access. This way it feels like anyone instead of entering the reference into browser would make their own PHP code that would acces those files from my server (which would make this act to increase security useless little bit). Correct me If I am wrong and it is not this easy.
I feel paranoid that it is not safe enough solution. Correct me If I am wrong and it is totally safe and preffered solution.
Too Long, Didn't Read
Is copying and pasting and customizing .htacess file safe enough to make directory forbidden only acessible by my PHP code to retrieve data from there and is it useable on most platforms?
I have recently found in right bar of similar questions this one (How to secure database configuration file in project?), yet I am not sure whether it can be used in my case, too, and how to do so.
As #Darkbee stated, the simplest way is to have the file outside your website root. This would be accessible on the server, but not to the public under any circumstances.
The alternative is to set the permissions to 400 on the file.
.htaccess could block access, but not blocking access to the server (which needs access) is just a long way of doing what would be simpler just using permissions.
I have a folder (/files) and I have tons of files there that users can download. I want users to be able to download their files only and no be able to see others people file.
For example:
User A can only view and download:
- file1.doc
- file2.jpg
User B can only view and download:
- file3.txt
- file4.jpeg
User C can only view and download:
- file1.doc
- file2.jpg
- file3.txt
My idea was to put all files in the same folder so all users knows where to go. My question is: Can I use .htaccess or should I build a PHP scripts for this? What about security (which one is more secure)?
Thanks
Is it an open directory, to start with? What you could do is create a subfolder for each user, put their files in there and then assign appropriate permissions in .htaccess for said folders. However, this would require some security integration with your OS (i.e., users would have to have accounts on your machine, not just your web application)... A quick and dirty -- and insecure -- alternative would be to prepend all uploaded filenames with the username (e.g., 'file1.jpg' uploaded by 'foobar' could be named 'foobar.file1.jpg', for example), then it's just a case of your PHP script returning only those files with the respective username and perhaps stripping that part out when displaying (or again, you could use folders, as long as your script can create a new folder per user, when one doesn't exist). Another option, which is slightly more secure is to create a hash of the file and usernames in a database, rename all uploaded files with this hash and then query the database appropriately.
The best solution would definitely be OS managed accounts, a I first mentioned, but it entails more overhead.
Build a PHP script where you use readfile to send the file to the browser. This way you can restrict access for individual files, and use the authentication system you already have.
You can certainly use either htaccess or PHP for this. Neither are more secure, as far as I know, that the other - though done wrong both can permit access where none is intended!
PHP might be marginally better, since you have more flexibility (in terms of integrating it with other PHP authentication, say) and you can put the folder outside the usual web root, which is good practise anyway.
This question already has answers here:
How to secure database passwords in PHP?
(17 answers)
Closed 9 months ago.
I have a great php mySQL login script that works fine. Is ther another way to provide all my access info without revealing it in the script? Right now I show all my security access info which I think is not safe.
Can I hide this?
Here is what I'm referring to:
$host="localhost"; // Host name
$username="XXXXXXXXXX"; // Mysql username
$password="XXXXXXXXXX"; // Mysql password
$db_name="XXXXXXXXXXX"; // Database name
$tbl_name="XXXXXXXXXX"; // Table name
Create database.php, move your code snippet above to database.php, then ..
include "database.php";
At the top of each page that needs a database connection.
First step: Put all mysql api into separate file, than include it in other scripts.
Second: Deny access to sql config\api file due configuring your server.
btw, whom do you show "show all my security access info"?
There is no easy way to do this, I would suggest storing the variables in a separate file and then just including the data. If you're not happy with others reading the data why not create a separate user specifically for the script? That's the way I'd do it.
If you want to give that script away and ecrypt the whole file before, you can always use Zend Guard
http://www.zend.com/en/products/guard/
As long as php interpret your script before it's send to the client you're safe. If you have access to apache conf files you could try something like this.
http://www.brianhare.com/wordpress/2011/02/18/hiding-mysql-passwords-in-php-using-apache-environment-variables/
If you are going to include the file at the top of your script it's important that you give the file an extension that will be interpreted (.php) or prevent them from being served in the .htaccess file. Otherwise you might risk that the webserver serve it as text upon request.
It will have to be defined somewhere. I would make sure you have suPHP installed so you can set your permissions to 400. Then include the file which has your definitions, like connection.php etc. This is very secure as it allows the php files only to be read by the server / your account.
Client machines do not have access to source code for server-side processes or any PHP variables: only output. Unless you provide a specific mechanism to display variables (i.e. debugging functions like var_dump) in your PHP script, then it is secure. Also, your server has to be set up to process PHP files and render the script's output instead of delivering the raw code as if it were plain HTML, but simply installing PHP usually takes care of that problem.
Then there is a broader issue of level-of-access with collaborators or others who have server access: and that is why it is good to house your credentials in a separate file that you exclude from public environments like GitHub. That is all I will say about that, as every case is different, especially when you toss in file permissions and file ownership. It should be noted, however, that the MySQL user permissions can also be limited, which adds an extra layer of insurance in case the wrong person comes across the credentials.
I am new to web development and I'm learning PHP in order to sell a few binary files (shared Linux host). The site is not yet live.
My php scripts (50% borrowed code, 50% self-written, 95% fully understood) login to MySQL to READ the items for sale, and WRITE sale transaction data into another table. Functions.php, located in a subfolder of the webroot, contains the login name and password for MySQL.
Q1. This doesn't seem secure to me. How should the login/password info be stored so the scripts can access it? If functions.php was stored outside the webroot, could the .php files located in webroot #include (PHP "require_once") it? (I did try this once and my scripts broke in a way that seemed permissions-related -- if I knew it should work I'd keep plugging away at it)
Q2. I am unsure where to store the binaries that purchasers can download. Is it correct that savvy users can somehow find / download them (without paying) if I just store them in a subfolder of the webroot? Is it possible to use a .htaccess file to block access to the "binaries" folder within the webroot? Can black-hats get at / modify a .htaccess file?
Q3. Would it be a better idea to store the binaries (max=4Mb) in a MySQL table and copy them from there to a temp file in webroot before each download, then delete?
Q4. Can anyone recommend a set of scripts that manages this sort of thing that I could review / modify rather than reinventing the wheel?
Thanks
Q1 - Your MySQL password and other application specific settings should be stored in a separate file outside of your webroot. You can either put it out of webroot directly or restrict it via .htaccess. You can include the file or read from it as long as you know the path.
Q2 - The binaries should also be stored outside of the webroot. The ideal way to serve them would be to have them downloadable via a PHP file. This way you can do authentication before the file is served and you can make the links temporary so that users can't share it with other people
Q3 - If you use the above method, you don't need to store it as a BLOB in MySQL
Q4 - I haven't really come across anything that does and is a library/autonomous script. Serving them via the correct headers shouldn't be too difficult though.
Not sure if best practice, but this is how I'd approach it:
Q1: I store MySQL login information, along with local paths and other settings, in a config.inc.php file outside of the web root. I can then include that at the start of each script. I also use a database.inc.php which connects to MySQL and selects the database (plus a few database functions). In theory it isn't insecure inside the web root as being called directly will only execute the PHP, not display the contents of it. Storing an XML config or similar is different however!
Q2: If downloadable binaries are stored within the web root then they could be downloaded if the right URL is discovered. Instead they should be stored outside the web root, and a PHP "gateway" script serves the contents of those files if the request meets the right conditions. You may want to store a token with each purchase in your database, and only valid tokens are permitted to download the files. An example of a download script is here.
Q3: I believe it's better to use the file system to store files, rather than a database. It won't improve security over my answer to Q2 if that's what you mean.
Q4: You could try existing shopping cart software. Magento supports downloadable products.
Hope that helps
I accept file uploads from users. Each file has a pointer in the db which has info on the file location in the filesystem.
Currently, I'm storing the files in the filesystem non categorically, and each file is currently just named a unique value. All categorisation and naming etc is done in the app using the db.
A factor that I'm concerned about is that of file synchronization issues.
If I wanted to set up file system synchronization where, for example, the user's files are automatically updated by bridging with a pc app, would this system still work well?
I have no idea how such a system would work so hopefully I can get some input.
Basically, is representing a file's name and location purely in the database optimal, especially if said file may be synchronized with a pc application?
Yes, the way you are doing this is the best way to do it. You are using a file system to store files and a database to sore structured data.
One suggestion I would make is that you create a directory tree on the file system. You may one day run up against a maximum files per directory limitation of your file system. I have built systems that create a new sub directory for each day or week.
Make sure you have good backups of the database as well as the document repository.
All you need to make such a system work is to make sure the API you use (or, more likely, create) can talk to the database and to the filesystem in a sensible way. Since this is what your site is already doing anyway, it shoudn't be hard to implement.
The mere fact that your files are given identifiers instead of plain-English names is mostly irrelevant with regard to remote synchronization.
Store a file hash in the database rather than a path (i.e. SHA1) and have a separate database connect the hash with the path. Write a small app that will synchronize the hash database so that when you move your files to a different location it'll be easy to build a new database with updated paths.
That way you can also have the system load the file from a different location depending of which hash database you use to locate the file so it offers some transparency if you need people to be able to access the same file from diverse locations (i.e. nfs or webdav).
We use exactly this model for file storage, along with (shameless plug) SabreDAV to make it seem to the end-user it's a normal filesystem.
I think this is a perfectly fine model, as long as looking up the file is documented and easily retrieved there shouldn't be an issue. Just make backups of your DB :)
One other advice I can give, we use an md5() on the file-id to generate a unique filename. We use parts of the files to generate a directory structure, for example.. id 1 will yield: b026324c6904b2a9cb4b88d6d61c81d1, the resulting filename will become:
b02/632/4c6/904b2a9cb4b88d6d61c81d1 The reason for this is that most stable filesystems can become very slow after a high number of files (or directories) in one directory. It's much, much faster too traverse a few sub-directories.
The Boring Answer™:
I think it depends on what you wanna do, as always :)
I mean take your regular web hosting company. Developers are synching files to web servers all the time. Would it make sense for a web server to store hash-generated file names in a db that pointed to physical files? No. Then you couldn't log in with your FTP-client and upload files like that, and you'd have to code a custom module to get Apache to work etc. Instant headache.
Does it make sense for Flickr to use a db? Yes, absolutely! (Then again, you can't log in with an FTP-client and manage your photos—and that's probably a good thing!)
Just remember, a file system is a (very simple) db too. And it's a db that comes with a lot of useful free tools.
my 2¢
/0