1

Versions of this question have been posted numerous times, but none of the solutions I've found on this site have worked so far. I'm trying to redirect away from files, not web pages. I actually need to know if this is even possible, since I learned that PHP is incapable of doing this. Here's an answer from a previous question I asked:

The web server will first check if it exists and if it does, it will serve the file immediately. It does not go through any PHP code. Therefore you cannot write any PHP code that will intercept this request and block it.

We have a folder on our site with a path of /downloads/, containing files we don't want just anyone to download.

I want to put a script in our main JavaScript file that says:

  • If file is is /downloads/
  • If user comes from referrer allowed_domain.com, allow access to files in /downloads/
  • Else redirect to homepage or 404

My attempt (didn't work)

if (top.location.pathname === '/downloads/private.zip') {
  if (document.referrer !== "http://www.allowed_domain.com") {
    document.location.path = "/downloads/private.zip";
  }
  else {
  document.location.path = "/404";
  }
}

Constraints

I cannot use .htaccess. Our hosting provider is running Nginx, not Apache. I've tried using Nginx config code, but I have to send it to them to implement, and it didn't work and they won't help me.

And yes, I know that this is a super, super insecure solution for restricting access. My company is working on a more formal solution, but until then, I need to implement something temporary to deter users who lack the computer knowledge or motivation to get around the redirect, and this is pretty much my last option.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Jesse
  • 508
  • 5
  • 12
  • Who told you that quoted statement? It's plain wrong, of course you can configure your web server to involve PHP instead of serving the files directly. And you need to do this on the server side, there is no clientside javascript involved in a document download. – Bergi Feb 22 '17 at 23:24
  • @Bergi are you talking about placing the file outside of `public_html` and delivering it through PHP? Because I'd love to do that, but my hosting provider doesn't support it. – Jesse Feb 22 '17 at 23:27
  • Yes, something like that, however I can hardly believe nginx wouldn't support this (unless it's an arbitrary restriction imposed by your hoster for your payment category) – Bergi Feb 22 '17 at 23:30
  • @JesseRogers Can you change the directory name or move the files? If so, let PHP deliver those files via `index.php?file=myfile.zip` while never revealing the directory. – JM-AGMS Feb 22 '17 at 23:30
  • @Bergi I don't think it's that Nginx doesn't support it, but that the company hosting my site's web server doesn't allow it. – Jesse Feb 22 '17 at 23:31
  • @JM-AGMS Can you elaborate on this? Sorry, I'm super front-end oriented, so my PHP skills are remedial at best. And yes, I have full control over the files and their location. I just can't move them outside of `public_html`. But yes, if I can deliver the files without revealing the URL, that will suffice for now. – Jesse Feb 22 '17 at 23:33
  • @JM-AGMS Then simply move them or change the directory name. Users requesting the files will get a 404. – JM-AGMS Feb 22 '17 at 23:35
  • @JM-AGMS Okay, to clarify: the link to the file is on another website for which I don't have server access. I only have access to markup on that site (It's a Zendesk portal). Will this still work? – Jesse Feb 22 '17 at 23:41
  • @JM-AGMS alternatively, maybe I could link to a _page_ on our main website that has a redirect rule based on referrer, and then use your technique to serve that file from a direct download link on that page. – Jesse Feb 22 '17 at 23:43
  • @JesseRogers You don't have to change the markup if you change the directory name. Users who visit any known link will get a 404. If you want to serve users the files but without revealing the direct url, you'll simply use a `index.php` to control everything. This can help you get started: http://stackoverflow.com/questions/3697748/fastest-way-to-serve-a-file-using-php – JM-AGMS Feb 22 '17 at 23:48

1 Answers1

1

This problem is not solvable in JavaScript, even in the very limited and insecure way that you are proposing. The problem is that a request to /downloads/private.zip directly returns the contents of that file - it doesn't load any HTML page, so the browser will never see or execute that JavaScript code.

A way to solve this would be to have a PHP file that handles any request to that directory, checks whether the user has permission to see those files, and then returns the requested file or a 404. But for that you need some form of configuration, and you've already told us you can't do that either.

A third solution, one that is very silly but would work (for unsavvy users) in this very constrained situation would be to replace all links to the forbidden resources with a snippet of JavaScript that directs the user either to the file or a 404 page. However, from your question it seems very likely that you're trying to prevent access from users coming from sites outside of your control, in which case this won't work either.

Bottom line: This is not a solvable problem if you don't have the ability to configure your web server.

AmericanUmlaut
  • 2,817
  • 2
  • 17
  • 27