Custom Log File with Correct Permissions - php

I have a processing file for my website's payments. It works just fine, but what I would like to do is log all the requests to this page so that if anything throws an error, the raw data is saved and I can process the transaction manually. The processing file uses fopen to write to the log file in another directory.
What I have right now is a separate folder on my root directory with permissions 755. Then a log file inside with permissions 777. The processing file that writes to the log file, in PHP if that matters, is set to 777.
This works right now, but the log file is publicly available. I know I can be doing this better and that the permissions aren't correct. How can I do this better?

Put the log file outside the document root. The PHP script that writes to it will still be able to get to it (via the full path) but Apache won't be able to serve it.

I came across this whilst searching the answer for myself. I don't believe there is a simple "permissions fix" to do what you want and perhaps the safest way is to put the log files outside of public_html directory.
However this can be a nuisance sometimes - especially if you are wanting to e.g. catch paypal ipn dump text in a log file, but not have it publicly accessible.
In such cases, you can use .htaccess file directives to allow write from script, but deny reading from public access.
For example, this works for me (Apache .htaccess in root public_html folder);
<FilesMatch "mycustom\.log">
Order allow,deny
Deny from all
</FilesMatch>
and if you have multiple logs you want to protect, use it like this, with "Pipe Separated";
<FilesMatch "mycustom\.log|ipn_errors\.log">
Order allow,deny
Deny from all
</FilesMatch>
It is worth noting that the above directives are deprecated as of apache 2.4 and you may wish to consider using more current directives instead: https://httpd.apache.org/docs/2.4/howto/access.html
Hope that helps you!

Related

Allow access to file ONLY FROM specific PHP file/ dir on same server

I've been pulling my hair off trying to find a solution for denying access to a file for all AJAX/ PHP/ in-browser requests EXCEPT when they come from one (other) directory/ file on the same server.
I have a .htaccess in the directory of the JSON file. The file is fetched by a CMS plugin as follows (pretty standard):
Javascript makes an AJAX call to a PHP file on the server, called handler.php.
handler.php then retrieves the contents of the file and returns it to JS.
I can't use rewrite rules, as it is not a prereq. for the CMS. I also can't set a known domain name, as it is dynamic. Ideally I would do Allow from SELF.
I have tried the following .htaccess configs without luck:
Order Deny, Allow
Deny from all
Allow From <ownDomainName/subpath>
Or:
Order Deny, Allow
Deny from all
Allow From <ownDomainName/subpath/fileName.ext>
I tried with setEnv directive too, and a mixture of others involving using <Files>, <Directory> and <Location>. If I just Deny from All the PHP cannot access it. Is there any solution for restricting access to a JSON file?
Also, does it have anything to do with the fact that I am testing on localhost?
There are 2 types of access to the file.
From web, where .htaccess rules or server (apache) config is applied.
By app or script running on the server machine, where filesystem permissions are applied.
So you can deny all requests in .htaccess file, but PHP script still can access the file via FS (dependent on FS permissions).

securing outward-facing website db configs

I'm adding some database usage to a public facing site, and I wanted input on what the most secure way to store mysql connection information might be. I've come up with a few options:
First I could store the config in another directory, and just set the PHP include path to look for that dir.
Second, I know there are some files that apache won't serve to browsers, I could use one of these types of files.
Third, I could store encrypted files on the server, and decrypt them with PHP.
Any help would be much appreciated.
Storing the config outside of apache's document root is a must
You can configure apache to disallow any files with htaccess.
in the config folder add a .htaccess with the following
order allow,deny
deny from all
If you don't want to use .htaccess as #johua k, mentions, instead add
<Directory /home/www/public/config>
order allow,deny
deny from all
</Directory>
to your apache config.
This will deny any files in that folder from being served to anyone, which is fine since php doesn't care about htaccess you can just
include('config/db.php')
If you properly config your php scripts, they should never appear in plain text.
so a file like
define('mysql_password', 'pass')
would never display that text.
If you are worried about a shared hosting environment and another use having access to read this file then you should evaluate the security of the linux installation and the host. Other users should have any browsing access to your file. From the web files marked php should never return source.
You can explicitly tell apache not to serve the files ever, so they would only be include() or require() able.

PHP change folder permissions for outgoing commands only

I have a file sharing website in the making where I am allowing the visual and function part of pages work. This runs into a problem when I want to allow server side scripting like php pages to be uploaded. This php (etc.) page could easily back link and delete files which I obviously would not want. I have changed the permissions many times to test but this also stops my php files from uploading and renaming files to these folders. I do want to allow these file types but im not sure what I can do.
I was thinking I could do this through .htaccess but I wouldn't know how.
Any suggestions?
I'm not sure, but it sounds like you want to allow arbitrary file uploads (including .PHP scripts) but to prevent any of them from being executed on the server side.
I would recommend creating a file storage directory that is not web-accessible (e.g. put it outside your www-root or use a .htaccess file to limit direct access). Then have your PHP scripts upload to that directory. Create a download script and have download access to those files go through that script, so that e.g. PHP files cannot be invoked remotely.
If I understand correctly from reading comments:
You want users to be able to upload any file. Including code. Including .php, .asp etc.
You want the users to be able to execute this code, but to limit the code to a "sandbox" environment.
Seems to me you should write your files to a specific location, which has its own document root/vhost (http://exec.domain.tld).
On that vhost you could set security, ie:
AllowOverride None # disable rewriting and such
php value disable_functions dl,exec,passthru,system,shell_exec,popen # disable functions
And to top it off (!important) set basedir restrictions to the vhosts document root
<Directory /srv/www/exec.domain.tld/docroot>
php_admin_value open_basedir /srv/www/exec.domain.tld/docroot
</Directory>
I haven't actually set up this environment, but I feel this is your best starting point. And I do think it'll work, if you fix the typo's/parameter name errors i might have made :)
I think it's not about permission, but php execution.
You can turn off php engine on a directory using .htaccess file, like this:
<IfModule mod_php5.c>
php_flag engine off
</IfModule>

Disabling download of php files if PHP is not installed

My university has multiple servers which have the same data mirrored across them, so I can access for instance
foo.uni.edu/file.php
bar.uni.edu/file.php
The thing is, not all servers have PHP installed, so anyone could possibly download my php files if they made the connection through a server which didn't have PHP installed.
Is there a way, possibly with .htaccess to avoid this? As in, only allow opening PHP files if PHP server is installed?
If it's possible to store files outside of the document root, you could work around the problem by storing all sensitive data outside the docroot. You would then have your publicly accessible scripts use include to access those files.
So, if you upload to /username/public_html, and public_html is your document root (eg, foo.uni.edu/file.php is /username/public_html/file.php), then you would upload to /username/file.php instead and place another script in /username/public_html which merely contains something like include('../file.php');
This is good practice in any case, in case a configuration error on the server ever stops PHP from being parsed.
You could also try using IfModule and FilesMatch to deny access to PHP files if mod_php isn't enabled:
<IfModule !mod_php.c>
<FilesMatch "\.php$">
Order Deny,Allow
Deny from All
</FilesMatch>
</IfModule>
If this doesn't work, try !mod_php5.c instead.

Map only accessible for webserver and not for other users

On my site i use a lot of includes, the most of the includes should only be accessible for the webserver and not for the rest of the world. So if i include "../include_map/file.php" in a page on my site, it should not be possible to request with an URL by other users in the world ("website.com/include_map/file.php"). Is there a possibility to protect the map with the include files so that only the webserver can include the files?
PHP can include files from everywhere (also non public directories) on the servers harddrive.
for example, if your htdocs is located in /var/www/domain/htdocs/ you can also include files located in /var/www/domain/include_map while the webserver wont be allowed to read from there (if configured properly).
you can then test to access the file with www.yourdomain.com/../include_map/file.php.
if you can still access it like this, your webservers configuration needs some attention to prevent others from reading your logs and other things.
another way is to deny access to the directory via .htaccess or apache config. php can still include the files, while users cant access them from the internet.
in the apache config you would do something like:
<Directory /inlcude_map>
Order Deny,Allow
Deny from all
</Directory>
in a .htaccess file you could write
Order Deny,Allow
Deny from all
the .htaccess file should be located in the directory you want to secure. Consult your server provider to find out which way is best for you. As stated in the comment you have to find out if .htaccess is an option for you first.
You could do as zuloo said. If you want this to work under any condition you could use a constant for this.
The file including:
define('IS_APP', true);
require_once('some/file/to/include.php');
// your code here
The included file:
if(!defined('IS_APP')) {
die('No direct access');
}
// your code here

Categories