Today, web security has been a hot issue for many web developers since many hackers are getting smarter and smarter in attacking intercept and resend network packets that do not belong to them which are terribly dangerous. Therefore, to prevent any bad things happen to your site, we show you simple ways as solution which is far from a complete solution but considered enough to give you a general view of how tokens and simple protocols can enhance security in your websites.
- The One-Time Token Concept
In order to tie every HTTP response to a token string that will be valid only for the next post request. Simple steps of breakdown are conducted as follows:
1 The client makes a GET request by typing the URL or a page or by clicking on a link
2 The server generates a random token. Subsequently, it stores a copy of the token in the session and embeds a copy of the token in the <form> tag of the response it sends to the client.
3 The client processes the content, and sends a POST request to the server, say when the user clicks on a button, which contains the randomly-generated token.
4 The server receives the request and proceeds with processing it only if the attached token is equal to the one stored in the user’s session.
5 The server invalidates the token and returns to step 2, where it formulates the response with a new random token.
In this manner, it cannot be repeated because the token it contains is no longer valid after the request is sent to the server even if a critical request sent to the server is intercepted by a malicious user. This will work the same if the user unintentionally presses F5 on the keyboard and resends the request after posting information to the server.
- The Solution
We update the markup to add a hidden field in order to prevent a POST request from being repeated which will store the token.
Further step is to create a function that produces a random token and embeds it both in the hidden field and the session collection.
Next, we change the Page_Load() function to only display the posted data if the posted token is equal to the one stored in the session.
Finally, to generate a new token before the final output is sent to the client, we override the OnPreRender() function. This is what makes it a one-time token, because it’s renewed every time a new request is sent.
It works just as it did before, when you submit the form by clicking on the button. But you’ll get the following error if you try to simulate the reply attack by refreshing the page because the token that is sent with the form is no longer equal to the one stored on the server:
This way, we can distinguish valid button-click submissions from falsely-repeated requests.
- Modify it even Better
Since they’re using the same session token key, one of the problems with this code is that if you have two tabs in your browser pointing to the same page, posting one will invalidate the token of the other which can be directed by adding a token ID that will make sure each request-response sequence happening in one tab will use its own set of unique tokens and will not interfere with other requests on the same page. To go back to the TokenizedPage class and add a TokenID property is the first order of business. Since the first time, this property generates a random ID in the initial GET request and stores it in the ViewState collection for future reuse.
Next, we will adjust the SessionHiddenToken property to use the TokenId property instead of using the Page. Title property.
The interesting part is that we don’t need to make any other change and the new mechanism will work with all pages that come from TokenizedPage.