Simply described:
Pass in a
GET parameter (or query string parameter) a random page number of your choice.
This random number is generated by your server ( c# function) and each time a number is generated, it is kept in a
mechanism on the server. You could use files, databases, caching or session
variables. Its up to you. This list will grow adding all the random numbers
already visited. When a page requested contains the same number as one used
before, you may assume that the page is a FAVORITE link that has been used or a
BACK in the browser history since the page numbers should never repeat. It is
as simple as that and prevents any refresh of the current page but also
prevents going BACK in the history of the browser.
Process is simple:
Look for a
parameter passed in the GET vars (Query string). If this variable doesn't
exist, bump to the login screen.
If the
variable is found, look it up in the tracking system to match the pages seen.
If the page number was already used, bump to the login screen
Add the
current page number to the tracking system (this number must not be used
anymore)<script>
</script>
Create a new
page number from a random system avoiding numbers already used
Append this
new page number to all links in the page
From this
point on, any link will look at least like :
asdf.aspx?random_page_number=987
And the
number should always change automatically on each page request. All the links
in the page ask for the same number and it's normal. The point of adding this
number to the links makes it impossible for a user to go back in its history of
press back since he will ask for a URL containing the random variable number
that was already used before when the page was asked.
Potential security flaws:
<script>
</script>It is
possible for anyone to copy a URL and append whatever number he knows has not
been used yet; therefore, the person can re-ask the page anew. A quick fix to
that is to create a hash of the page number. (Get something complex that is
very hard to crack, not just a sha1 or md5, that's too easy) That hash number
must be based on the random number already generated. If you append this hash
with the random_page_number you created, just add one more step to your initial
verification to recreate the hash from the page number. If the new generated
hash and the provided hash are the same, you can assume either the person has
cracked your hash code algorithm therefore your security is cracked or that the
hash provided and the page number have not been tempered with…
Problems concerning this method:
This method
obviously takes a lot of space in memory to work with depending on the way your
implement the page tracking. It's certain that if you have 5 pages to visit
max, a random number of 0 to 99 is great; this means the person can visit a
total of 100 pages before touching the limit. This then bumps the user back to
the login and the tracking system is reset for this user's session. Why put a
limit? Simple, first of all random number generation has to have a limit;
second, you want to limit the size of the tracking stack. Having too many items
in the stack depending on your tracking method can be dangerous. For example,
we chose a simple session based tracking with 0 to 999. This limits us to 1000
page navigated, but the problem is not there, imagine the numbers 0 to 999
lined together with commas. This makes the session data very heavy in the long
run. Databases will handle this more gracefully but to the cost of adding
several new SQL queries on each page just for that...
Conclusion
Good system,
lots of alternative ways to build it, lots of alternative ways to secure it.
Have fun with it…
Points of Interest
Did you learn anything interesting/fun/annoying while writing
the code? Did you do anything particularly clever or wild or zany?
History
Keep a running update of any changes or improvements you've
made here.