Search code examples
asp-classic

How to pass value parameter in url that cannot excecute directly in url?


So i have this program that sending notification value to other page and show the notification, but the problem is you can edit the value in the url,

    If lngErrNo <> 0 Then
        response.write "Error while update Product."
        response.end
    Else
        v_strMsg = "Edit Kelipatan Jumlah Pesanan Berhasil!"
        
        Response.Redirect "global_notification.asp?strMsg=" & v_strMsg
    End If

the problem is you can edit v_strMsg in url for the example abc.com/global_notification.asp?strMsg= "anything you can edit the value here", and the display page is look like this

<body>
<table class="1" width=70%  cellpadding="0" cellspacing="0">
        <tr>
            <td colspan="3" background="images/bgtable.gif"><div align="left" class="fontwhiteheader13">&nbsp;&nbsp;
              ATTENTION!!</div>
            </td>
  </tr>
          <tr>
           <td valign="top"><table width=100% height="360" cellpadding="2" cellspacing="2" bgcolor="white">
        
          <tr>
            <td align=center class="fontblueheader13"><%=Request.QueryString("strMsg")%>
            </td>
          </tr>
    </table></td></tr></table>
</body>

any possible way to sending the value without changing it to POST metod? i try htmlEncode but v_strMsg still can be edited in url, any suggestion?


Solution

  • You need a signed URL.

    A signed URL includes a digital signature that proves the request was generated by the server.

    The first thing you need to do is create a secret key:

    ' Generate your own key from:
    ' https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx
    
    Const secret_key = "G+KbPeShVmYq3s6v9y$B&E)H@McQfTjW"
    

    In this example it's a 256 bit key.

    You also need a hashing function:

    hash.asp

    <%
    
        ' Might as well store the secret key constant in this file:
        
        Const secret_key = "G+KbPeShVmYq3s6v9y$B&E)H@McQfTjW"
    
        Function Hash(ByVal Input, HashAlgorithm)
            
            ' Select the System.Security.Cryptography value.
            
            Select Case uCase(HashAlgorithm)
            
                Case "MD5"
                
                    HashAlgorithm = "MD5CryptoServiceProvider"
                    
                Case "SHA1"
                
                    HashAlgorithm = "SHA1CryptoServiceProvider"
                    
                Case "SHA2","SHA256"
                
                    HashAlgorithm = "SHA256Managed"
                    
                Case "SHA384"
                
                    HashAlgorithm = "SHA384Managed"
                    
                Case "SHA5","SHA512"
                
                    HashAlgorithm = "SHA512Managed"
                    
                Case Else
                
                    HashAlgorithm = "SHA1CryptoServiceProvider"
            
            End Select
            
            ' Convert the input to bytes if not already.
                        
            If NOT VarType(Input) = 8209 Then
                            
                Dim utf8 : Set utf8 = Server.CreateObject("System.Text.UTF8Encoding")
                
                    Input = utf8.GetBytes_4(Input)
                                                    
                Set utf8 = Nothing
                
            End If
            
            ' Perform the hash.
                        
            Dim hAlg : Set hAlg = Server.CreateObject("System.Security.Cryptography." & HashAlgorithm)
            Dim hEnc : Set hEnc = Server.CreateObject("MSXML2.DomDocument").CreateElement("encode")
                
                hEnc.dataType = "bin.hex"
                hEnc.nodeTypedValue = hAlg.ComputeHash_2((Input))
                Hash = hEnc.Text
                    
            Set hEnc = Nothing
            Set hAlg = Nothing
            
        End Function
    
    %>
    

    Now you're ready to sign your URL with a digital signature.

    ' Be sure to include "hash.asp"
    
    ' Your message:
    v_strMsg = "Edit Kelipatan Jumlah Pesanan Berhasil!"
    
    ' A unix timestamp:
    v_uts = DateDiff("s","1970-01-01 00:00:00",Now())
    
    ' NOTE: Your servers timezone should be set to UTC to generate a true unix timestamp, 
    ' but it doesn't really matter, as long as "global_notification.asp" is on the same
    ' server, or a server set to the same timezone as the page you're generating the 
    ' signature from.
    
    ' Now we create the signature as so:
    v_signature = Hash(v_strMsg & v_uts & secret_key,"SHA256")
    
    ' Finally, redirect to "global_notification.asp"
    Response.Redirect "global_notification.asp?strMsg=" & Server.URLEncode(v_strMsg) & "&ts=" & v_uts & "&signature=" & v_signature
    

    Example redirect:

    global_notification.asp?strMsg=Edit+Kelipatan+Jumlah+Pesanan+Berhasil%21&ts=1612794802&signature=61016c0a0460902cc4a19f092dcbb4fd818aa9c88d2631e087868253e73983da

    Now to validate the signature on global_notification.asp:

    <!--#include file = "hash.asp" -->
    <%
        
        Dim v_strMsg, v_uts, v_signature, v_uts_now
        
        v_strMsg = Request.QueryString("strMsg")
        v_uts = Request.QueryString("ts")
        v_signature = Request.QueryString("signature")
        
        ' Do some basic validation first.
        
        If v_signature = "" Then
        
            Response.Write "Missing Signature"
            Response.End()
            
        ElseIf v_uts = "" Then
        
            Response.Write "Missing Timestamp"
            Response.End()
            
        ElseIf NOT Len(v_signature) = 64 Then
        
            Response.Write "Invalid Signature"
            Response.End()
        
        ElseIf NOT (IsNumeric(v_uts) AND Len(v_uts) = 10) Then
        
            Response.Write "Invalid Timestamp"
            Response.End()  
        
        End If
        
        ' Validate the signature. To do this, we simply recreate what we're expecting the signature
        ' to be, and compare it to the one being passed.
        
        If NOT Hash(v_strMsg & v_uts & secret_key,"SHA256") = v_signature Then
        
            Response.Write "Invalid Signature"
            Response.End()
        
        End If
        
        ' Now let's set an expiration period for the link, say 30 seconds? (or 86400 seconds for a day, 604800 for a week etc).
        
        v_uts = Int(v_uts) + 30
        v_uts_now = DateDiff("s","1970-01-01 00:00:00",Now())
        
        If v_uts_now >= v_uts Then
        
            Response.Write "Expired Link"
            Response.End()
        
        End If
        
        ' At this point, everything is good.
        ' Go ahead and display the message:
        
    %>
    <body>
    <table class="1" width="70%"  cellpadding="0" cellspacing="0">
      <tr>
        <td colspan="3" background="images/bgtable.gif"><div align="left" class="fontwhiteheader13">&nbsp;&nbsp;ATTENTION!!</div></td>
      </tr>
      <tr>
        <td valign="top"><table width="100%" height="360" cellpadding="2" cellspacing="2" bgcolor="white">
            <tr>
              <td align=center class="fontblueheader13"><%=v_strMsg%></td>
            </tr>
          </table></td>
      </tr>
    </table>
    </body>
    

    Now if you try and change the message (or the timestamp) you'll get an Invalid Signature error. The only way to generate a valid working link is to know the secret key, which of course is hidden.