Hi All. Apologies if this is better mean for begin...
# cfml-general
n
Hi All. Apologies if this is better mean for beginners channel. We're trying to figure out the best / modern way(s) to restrict direct access to protected pages that are behind other pages in a process (e.g. I search a db via a search form and see results and then click on results to see more details). We don't want users (or bots) to be able to get to the following pages unless they start at the search form first. In the case of protecting pages behind forms, we've been using CSRFGenerateToken. But, this tag seems to be used with forms only. For subsequent pages without a form to pass CSRFGenerateToken, it's not clear how best to protect access to the following pages in the process (short of a pw). Is there a standard / preferred way to do this?
m
we don't keep pages under the webroot (eliminating direct requests), and leverage our frameworks routing mechanism instead, then during the setup request portion of the request lifecycle we verify the user has authorization for where they are requesting.
2
s
Look into application.cfc, specifically the on request, cfc and session start/end… for placing authorized/not authorized logic.
n
@Matt Jones That's very interesting. We have kept documents outside the webroot, but I am having trouble thinking about how pages (unless they were static html pages (or similar) would be outside the webroot. In terms of authorization, this would not be a pw type situation. It would be more of a public "Search the directory" feature where the user searches the form, then sees a list of results, then clicks on a single link to see more details on the results, and then maybe clicks a "Print" option (ie several steps in the process).
@sunnispoon OK, will do. By authorized / not authorized, so yo mean a login scenario? We're focused in this case on pages not behind a login. I'll google what you suggested - thanks!
m
authorized can be anything that you require to allow permission, like not having a variable defined from your search could count as not authorized. authentication would cover logged in users. I generally handle authorization of the 'is the user allowed' type in that request setup, and the rest like your 'must come from the search got this action' i handle in the controller that defines that action.
n
@Matt Jones Thanks. Quick follow up question - when you say that you authorize page access in the controller, what is the mechanism in the sense of do you set a cookie, session variable, or something else (e.g. look at cgi) to check on the following page that the request came from the intended previous page?
e
We use session vars to determine who has access to what and how they arrived to the page they are viewing. You can do the same, its not magic, its just a bunch of empty session vars with "toggle" states. As for securing the actual content, you can always keep it purely in the db and call it only after it meets your security requirements. Depending on your setup, it maybe faster than file retrieval.
n
@Evil Ware Thanks! So, for example, I'm looking at a search result list of contacts. Then I click on a contact's link to see a person's profile in more detail. That profile page that I linked to would check for the existence of a session variable set on the previous page. This would essentially disallow a bot or similar from getting to that profile page directly from the browser (ie circumventing the search and link process). Is that the idea?
e
1. You would want to encode your search page forms something unique for each session if you really want it "Secure", then on the details page, it would check for the existence of your sessionUniqueID from Page X. You can do this as sesssion.vars, you can even force timestamps with in a range, browser and ip address strings to match, so on and so forth. Really comes down to how technically expensive you want to make your search.
t
you could also enforce that via
CGI.HTTP_REFERER
which can be spoofed of course but it's an easy way to enforce the originating page coupled with a authentication session/client variable... you could hash a bunch of the client browser fingerprint to create a unique hash and then test for that hash on the second page too... so many ways to skin this cat
n
@Evil Ware For the search page and the results page, we use CSRFGenerateToken. That seems to work pretty well. It's the following page(s) that you link to (rather than using a search form) that I'm thinking about (since we see CSRFGenerateToken in forms, not links). I am wondering whether maybe just checking the CGI variable for the link from the authorized page would be a good way to go
@tattva5 It sounds like in a low security situation (ie a publicly facing search that doesn't site behind a login), cgi might be ok as a way to force most users through the main process.
@tattva5 When you write "client browser fingerprint" what are you referring to?
e
Create your own token hash, way better and more "cross engine". Then you can have hash(mysecret) linked to session.hash, now search form and session can be cross checked. That way contact result only displays if session and page hash match.
n
@Evil Ware Thanks. I know we have a secret key now per client instance, but your solution is a bit over my head. I will run it by someone more technical on this end.
e
This isnt hard, its easy. When you fire up your session search page, assign it a session. hash value,, assign the same hash value(s) to your form (how is up to you) on your details page, before any code is executed you check for session.hash and your secret page.has matching, if they are equal you render the page, if they do not, then do something. https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-h-im/hash.html Note, lucee has the same function and its faster.
n
@Evil Ware Thanks! I do understand hashing, so that's good. I'll have to think through the mechanics. It sounds like you are saying to create a hash of our secret key variable. Then set it as a session variable. Then, when the user get's to the profile page later in the process, that page will also hash the secret key and compare it to the session variable. If they match, then that means that this user came through the expected path.
👍 1
e
You got it.
n
Woohoo!