Home > Net >  .htaccess protected directory and curl
.htaccess protected directory and curl

Time:01-20

I want to disallow access to all files and folders in protected directory on my server.

I have used this in .htaccess file in that directory:

Deny from all

But the problem is I also want to use curl from another website to query one file in this directory:

$curl = curl_init();
$post_data = array();
$post_data['token'] = $token;
curl_setopt($curl, CURLOPT_POST, true);
$url = 'https://my-website.com/protected-dir/file.php';
curl_setopt($curl, CURLOPT_URL, $url );
$response = curl_exec($curl);
if (curl_errno($curl)) { 
     return(curl_errno($curl)); 
} else{
    return $response;
}

curl_close($curl);

Now I get error 22 from CURL. I want to protect direct access to all files and folders in that directory. What are my options?

  1. I can place this directory outside of web root, but how would I use CURL then? (what is the URL to that file?)

  2. other solutions?

CodePudding user response:

The easy answer is to leave the file inside the document root and then just add an allow exception to the .htaccess file, which lists the IP address of the remote server you want to allow hits from:

allow from 1.2.3.4
deny from all

But note this will allow any user on that machine to grab the file. The secure answer is to always put sensitive content outside the document root and never rely on .htaccess to protect you. Then create an authenticated proxy page for any exceptions.

public/
    index.php
    secret.php
private/
    secret_file

Where public is the document root, index.php is your regular site, and secret.php would be something like:

// run some checks to ensure that you're allowed to do this:
//   maybe check source IP
//   maybe check for a username and password
//   maybe check for a specific bearer token in a header
header('Content-Type: whatever');
readfile('/path/to/private/secret_file');

CodePudding user response:

It would seem (from comments) that this code is part of a WordPress plugin that can potentially be installed on any website. In which case this file needs to be "public".

The file shouldn't be in the protected directory to begin with. However, you can block everything except the file in question using a <FilesMatch> container and a regex/negative lookahead.

For example:

<FilesMatch "^(?!file\.php$).*">
    Require all denied
</FilesMatch>

Everything is blocked except for requests to file.php. Note that the Deny directive is formerly deprecated and you should be using the corresponding Require directive instead on Apache 2.4 . (But note that you should not mix both old and new authentication directives.)

I assuming that your script contains the usual validation, for example:

  • fails early on any non-POST request.
  • fails on any POST request that does not contain a suitable token parameter.
  • enforces a "delay" on any failed token requests to prevent brute force attacks.

You could also set a custom User-Agent string as part of the CURL (POST) request and check for this in your script or earlier in .htaccess - but that's just smoke and mirrors and doesn't really offer any additional "protection".

  • Related