2

Given a homepage at domain.com (e.g., https://example.com/), I want:

  1. outside requests to only be able to visit the homepage and no subpages
  2. that homepage to successfully redirect visitors to a subpage (for example, https://example.com/page1.html)

I can accomplish #2 with some simple JavaScript and window.location.href = example.com/page1.html. But for #1, is there a way to reject access to internal pages if the referrer is coming from my domain.com? Basically the flow I'm looking for is:

  1. outside visitor visits https://example.com/
  2. https://example.com/ redirects visitor to, for example, example.com/page1.html
  3. any attempt to visit example.com/page1.html directly fails with a 404

I get that this may all seem nonsensical in terms of what it does. That's by design. I want a website that sends visitors to internal pages, but only if they get there through the homepage redirecting them to it.

3
  • Why tag this as .htaccess? I'm not sure that this can be accomplished using it. Can you tell us more about the site? What you're asking for might make sense in some context, but I can't figure it out. This would be an SEO disaster, for example. Do you have server side scripting like PHP that you can build this logic? Commented Mar 9, 2021 at 23:46
  • I'm open to additional tags. I thought this might be possible with RewriteEngine conditions/rules. Yes, this might be an SEO disaster, but that's ok. It's not a design for search engines or one meant to be legible for search engine bots. Yes, happy to use server side scripting --- maybe using single page application style routing?
    – mix
    Commented Mar 9, 2021 at 23:55
  • 1
    What you describe could perhaps be done with .htaccess (and perhaps a cookie?), however, you still seem to be in the process of design and what you describe sounds more like a single-page-application (as you suggest). A single URL (the homepage) from which you conditionally serve content based on some criteria. No redirects, no additional URLs, no "access control". (?)
    – MrWhite
    Commented Mar 10, 2021 at 1:50

2 Answers 2

3

There is a simple way if you want the rules to be followed but not enforce them against deliberate spoofing. This looks something like this:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://www.example.com/.*$
RewriteRule (.+) - [R=404,L]

Someone with intent on bypassing this can spoof the referrer though. A better way would be for you to enforce visiting the home-page first in your code. Basically, you read a cookie and if it is not there, redirect to the home page. If it is there, do not redirect. Make the home page be the only one that sets the cookie, and they have to visit the home page first.

In PHP the function called session-start can be used for this since it starts or resumes a session. You did not say what back-end you are using but there are probably equivalents in other languages.

4
  • 1
    Would this work as written though? While you were posting this, I was composing my own answer which is similar, but additionally specifically allows for index.php to be come through. (I would have thought your version would not work unless www.example.com is actually on another domain)
    – davidgo
    Commented Mar 10, 2021 at 6:10
  • Sorry, had a typo. The RewriteRule should be should be anything with a least one character (+) not zero or more chars (*). This will sent a 404 to traffic not re refferred by the homepage that is also not the homepage. If your homepage is not / but something like index.html just change the rule to RewriteRule !^index.html$ - [R=404,l]
    – Itai
    Commented Mar 10, 2021 at 15:40
  • Is there a way to modify the RewriteRule to accept visits to domain.com AND domain.com/index.html but to exclude outside referred visits to domain.com/?some-GUID and domain.com/index.html?some-GUID? So this is really two questions: 1) how to accept domain.com without an explicit call for index.html and 2) how to exclude ? parameterized URLs (along with all other URLs)?
    – mix
    Commented Mar 10, 2021 at 21:13
  • 1
    There are many ways and it's possible with just a more complex RewriteRule expression but it will be clearer if you put multiple RewriteCond which get 'ANDed` together. So if you insert a second condition like: RewriteCond %{REQUEST_URI} !^index.html$ then the 404 will not apply to requests to index.html and another one is needed to apply when it has a query string, something like: RewriteCond %{QUERY_STRING} !^$
    – Itai
    Commented Mar 11, 2021 at 0:53
2

I've not tried this as my environment makes doing so tricky, but I posit something along the following lines will work in .htaccess

RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{HTTP_REFERER} !www\.example\.com [NC]
RewriteRule ^ -[R=404,L]

Of-course replace www.example.com with your actual domain, and if your default file is not index.php change the second line as well.

The idea is to allow /index.php to be accessed without restriction thanks to the second line, with lines 3 and 4 being used to produce a 404 error for anything else which does not have a referer. I note that you specifically asked for a 404 error. That error should more correctly be a 403 - Access denied.

1
  • 1
    -[R=404,L] - You have a typo here. Needs a space before the [. You should also anchor the HTTP_REFERER regex, otherwise, it will potentially allow a link from anywhere that simply includes www.example.com in the URL-path.
    – MrWhite
    Commented Mar 10, 2021 at 17:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.