views:

291

answers:

3

This question is similar to the one i asked here. But its related because I want to achieve the same effect. I want the users to be restricted to only accessing other pages on the site through the main page. The first page contains a frame for navigation and then a frame for content of the page they navigate to. I want it to be setup so that the only way they can access the content pages is by using this main page. So if the main page is http://intranet/index.html then they cannot get to http://intranet/other_page.html without using the link provided in index.html. Is this possible and if so what would the best technique be? I'm using apache to serve the site and I have php and javascript available.

+1  A: 

Check the Referer request header - it will thwart casual users with their browsers. It can be spoofed though - you won't fool a determined attacker.

False positives are possible though. Sometimes Referer is not set.

Seva Alekseyev
I'm assuming you need to do this within each page that is loaded into that frame and you could do that with php? And thank you for finally not blasting me about checking inputs and all that. All of the other answers flat out ignored the fact that i said the inputs are sanitized and I'm just trying to keep the average joe main users from toying with it. They will not have access to any of those tools they refer to!
controlfreak123
Yes, for each page. I recommend a PHP include to do the job. The value of the header is available as$_SERVER['HTTP_REFERER']
Seva Alekseyev
thank you. Your second comment was what I was looking for!
controlfreak123
also im interested under what conditions the referrer wouldn't be set?
controlfreak123
Seva Alekseyev
+4  A: 

That short answer is - no, it's not possibly, strictly speaking.

The long answer is that yes, you can probably come up with a reasonable approximation of this, but you do need to be aware of the limitations.

Fundamentally, HTTP is stateless. No matter what specific actions occur, your webserver will see a single request for /other_page.html and will need to decide whether to serve it or not. In order to have some kind of reasonable limitation, the first step is that you will have to have some way of maintaining server-side state. Without this you cannot match up any incoming request for other_page.html with previous requests. The good news is that PHP does have native support for server-side sessions.

(Without server-side sessions you could try to achieve this with client-side session cookies, or inspecting the referrer header, but then it's trivial for the clients to fake as these are just strings that they send you and you accept their word for it).

Now, you'd need to use this session to track whether a user has been to the first page before going to the other page - you could set a variable in the session when the first page is requested, and on every request for /other_page.html, ensure that this variable is set in the session before serving it. That at the very least gives you a reasonable idea that they have visited the first page in the current session.

However you have absolutely no way of knowing what link was clicked in the browser to request a particular URL - or even whether a browser was involved at all. All your server sees is a request for a particular resource along with some headers. One way to potentially simulate this is to generate a random string when /index.html is served, and add this as a query parameter to the link on that page. Then store it in the session, and when other_page is asked for check that the request includes a query parameter with the same random string.


But at this point it's time to take a step back and say - why do you want to do this? I can think of no good reason at all why this would be done. It is not an appropriate security measure - you'd need to do security properly, and if that's your motivation you should have asked for it. It's not a good method of enforcing a particular workflow on visitors either - whether this is a good idea at all is debatable, but instead of thinking of how to force people to go to page A before page B, think about exactly why it is you need them to do that, what your limiting factors are, and what's the least intrusive way of achieving them.

Don't forget - http://intranet/other_page.html is a Uniform Resource Locator that corresponds to the content you're serving from that page. If someone visits that address one day and sees a useful resource, why on earth should they not be allowed to see it again when they go back? I strongly recommend that you think about why you want to deliberately handicap your users' experiences, and go against the general way that the internet works, with your site.

Andrzej Doyle
The reason why i am trying to do this is because they want the design of the intranet to use frames so that the end user only sees the main page (/index.html) in the addressbar no matter what page they are on. But i don't want the users to be able to "view page source" see the thing they want is at "/other_page.html" and just type that into the addressbar
controlfreak123
and as far as not being able to go back to it another day. This is an intranet only accesible by domain authenticated users. The users are only going to be able to tamper with the data passed to the pages using the addressbar so I believe for simplicity, getting this functionality would prevent people with these limited tools from snooping around the site
controlfreak123
If you only concern is wanting them to see the URL as /index.html the easiest way to do that would be to use apache's mod_rewrite
eCaroth
Additionally, you can do this with conditions that specify which of the pages you want to show up as index.html OR you can use the referrer (as mentioned below by Seva Alekseyev), which is available to use for comparison in mod_rewrite RewriteCond conditional statements to specify which pages the referer must be. Just google mod_rewrite and there are tons of good examples and tutorials for this.
eCaroth
@controlfreak123: *Why* (referring to your first comment)? If someone views source to work out the URL of the specific page, and then types that into their address bar, then it's pretty clear that they *want* to see that page without frames. So: 1) if you're trying to do this to make their experience better, then don't because you're not; 2) if it's a business requirement that they **must** see the frames, then framesets will **never** fulfil this requirement. Put the "frame" part on every page using something like PHP `include`, so that the content of other_page.html always includes it.
Andrzej Doyle
framesets are pretty bad anyway and should be taken out and shot (:-)), but in this particular case it's wrong to have your other_page.html as a separate resource with its own URL, if it's never intended to be viewed as a separate resource.
Andrzej Doyle
i don't understand why its so hard to believe that we don't want them doing anything to try and snoop with the pages. There is more than just one page that could be loaded into the content frame. The whole purpose of using the frames is to keep them from seeing what data is being passed to the pages just from the standpoint of looking at the addressbar. I know how trivial it is for someone to break it with other tools but you have to understand these users don't know what to do if the folder they save stuff in doesn't show up right away when they click save as. Its like locking a glass door.
controlfreak123
It will only keep the honest people out. I have sanitized the inputs to the pages so they can't inject sql and such what I want is to make it a little harder for a dumb user to see the url with the data in it and be tempted to type whatever they want in there. My question is simply if it is possible to restrict it that way. Not if its unbreakable to do so.
controlfreak123
@eCaroth: i also like your answer. Does mod_rewrite change the url so that it won't show at any point the data sent by the get form?
controlfreak123
A: 

I too am wondering about this and do NOT want to go PHP or other such stuff yet. I doubt you can do this without another programming language though.

TC
Yes. Unfortunately i decided to try and get mod_authnz_ldap working to authenticate the clients with apache...only to learn all about the difference between authentication and authorization :(
controlfreak123