1

I have been stuck in this topic for a long time and I hope someone can help me.

I have an application written in asp classic. I must implement an antiforgery token in the form where I go to validate the data. My page is composed like this

<% Dim token
token = GetGUID()
Session("token")=token
%>
<html>
<head>
</head>
<boby>
...
...
<form method="post" action="../includes/CENT_FUNCTIONS.ASP">
<input type="hidden" value="<%=Session("token")%> name="token">
</form>
</body>
</html>

As you can see at the top in the asp code when opening the page I generate a GUID that I am going to save in a session variable. I generate the GUID with this vbs function

FUNCTION GetGUID()
    GetGUID = CreateObject("Scriptlet.TypeLib").GUID
END FUNCTION

So I'm going to save the session variable in a hidden field of the form. The action of the form goes to call another asp file where I will go to collect the form data to call a store procedure in the sql database. The file is written like this

<%
IF Request("token") = Session("token") THEN
    ID_CENT=Request.QueryString("ID_CENT")
    IDAZIENDA_CENT=Request("IDAZIENDA_CENT")
ELSE
    Response.Redirect "../notallowed.asp"
END IF
    
set command = Server.CreateObject("ADODB.Command") 
command.ActiveConnection = conn 
command.CommandText = "CAR_CENTRALINI_FUNZIONI" 
command.CommandType = adCmdStoredProc 

set objParameter = command.CreateParameter ("@ID_CENT", adInteger, adParamInput,,ID_CENT) 
command.Parameters.Append objParameter 

set objParameter = command.CreateParameter ("@IDAZIENDA_CENT", adInteger, adParamInput,,IDAZIENDA_CENT) 
command.Parameters.Append objParameter 

command.Execute , , adExecuteNoRecords 
                
Set command=Nothing
Set objParameter=Nothing

Response.Redirect "../Fonia/UT_Fonia_CENTRALINI.asp"

%>

So before collecting the form data I go to check if the token arrived is the same as the one stored in the session variable. But this comparison that I make in the IF condition always returns false.

Is this way I am using to generate and validate the anti forgery token correct? What am I doing wrong?

Thanks for any replies

fraguerr
  • 41
  • 7
  • 2
    what if user opened two instances/tabs of the same page? – Iłya Bursov Apr 04 '22 at 23:14
  • Have you inspected the values of `Request("token")` and `Session("token")` via a break point or by dumping to display? Are they what you expect? – Jon P Apr 04 '22 at 23:27
  • 3
    You also haven't closed the quotes for the value attribute in the hidden field. You want : `` – Jon P Apr 04 '22 at 23:30
  • If this is for CSRF you can always store the token as a cookie rather than a session value. – Adam Apr 04 '22 at 23:39
  • @Iłya Bursov makes a good point, is that the full code of `CENT_FUNCTIONS.ASP`, or just an excerpt? Because if you're setting a new token session on each page load, that would explain your problem. I'd still suggest using a CSRF cookie. In `GetGUID()`, check if the cookie exists, if not, create one and change your If Statement to `If Request.Form("token") = Request.Cookies("token") Then` and use `Request.Cookies("token")` in your form. Using a cookie you don't have to worry about the session expiring. – Adam Apr 04 '22 at 23:52
  • @Adam A Session is stored in a cookie. The issue is the malformed input tag missing the end quote on `value` as JonP suggests. Use `Response.Write()` to debug the values of both the `Request` and the `Session` tokens. – user692942 Apr 05 '22 at 06:21
  • But a session value is stored on the server. Plus the session cookie has a session expiration, not a date, It’s just always made more sense to store CSRF tokens as cookies with a long expectation date. The default session timeout is 20 minutes I believe, that just seems problematic. Also, it’s worth mentioning to the OP that they need to check that their form token actually has a value, otherwise it defeats the purpose. You could bypass the form page and post directly. No token set, no token expected. The if statement will pass whether checking against a session or cookie value. – Adam Apr 05 '22 at 06:41
  • @Adam session values are stored in memory on server this is correct but the session is persisted using a session cookie in the client internet browser. I don’t see how the session timeout is a problem, if anything it just heightens the security of the anti forgery token. – user692942 Apr 05 '22 at 11:28
  • Except it's not really persistent though. What the browser classes as a session length and what the server classes as a session length can never be synchronised. You can open a new tab, return later, and the browser is still in session, so your session cookie(s) remain, but your session on the server has timed out, so you lose all your stored session variables, what if you left a form open and unsubmitted? The CSRF token will fail. It's pretty unlikely, but it can be an issue. CSRF cookies tend to be the preferred method across all languages and are just as secure as using session variables. – Adam Apr 05 '22 at 13:10
  • 1
    @Adam In that scenario you want it to fail, CSRF tokens shouldn’t be long lived. – user692942 Apr 05 '22 at 16:25
  • A CSRF token doesn't need to be a secret between the server and the clients browser. Given the nature of a CSRF attack, it's a secret between the clients browser and a third-party attacker, preventing them from making changes to a users account on your server. And you can do that without having to use any server memory or database space. And isn't that what web development is? Finding the best and most efficient solution to a problem, never mind how small? This is a great in-depth explanation: https://stackoverflow.com/a/20518324/4901783 – Adam Apr 05 '22 at 17:45

0 Answers0