Security Classic ASP - ajax

Is this secure enough? I don't have any experience with classic ASP or VBScript.
I have a classic ASP page that takes in form data and sends it to another classic ASP page that makes a connection to the database. I use this for my CSRF token on the form input page:
<%
Dim token
token = CreateGUID()
Function CreateGUID()
Dim tmpTemp
tmpTemp = Right(String(4,48) & Year(Now()),4)
tmpTemp = tmpTemp & Right(String(4,48) & Month(Now()),2)
tmpTemp = tmpTemp & Right(String(4,48) & Day(Now()),2)
tmpTemp = tmpTemp & Right(String(4,48) & Hour(Now()),2)
tmpTemp = tmpTemp & Right(String(4,48) & Minute(Now()),2)
tmpTemp = tmpTemp & Right(String(4,48) & Second(Now()),2)
CreateGUID = tmpTemp
End Function
%>
<input type="hidden" ng-model="user.token" value="<%=token%>">
I'm using an AJAX call (with AngularJS if that matters) in the same page to post the form data to the page that will make a connection to the database.That page looks like this:
<%# LANGUAGE="VBScript" %>
<%If Request.ServerVariables("REQUEST_METHOD") = "POST" Then%>
<%If Request.Form("token") = Session("token") Then %>
'here I make connection to database and and insert rest of form data in database

OK, so let's go over this bit by bit...
You're getting all the fields of the current date and time, and using Right(..., 2) along with String(4,48) to zero-pad them. And then you concatenate them together. This results in... A string that represents the current date and time. For example, running this right now for me produces 20141212131100.
Firstly, it's definitely not a GUID, which is carefully specified to be dependent on time, hardware info and a bit of random. Clearly, as soon as someone sees this token, they will understand how it's made and how to forge it. They only need to be accurate to the nearest minute too! There is absolutely no randomness in this token generator.
So to answer your question, no, it's not secure. If you don't have access to a COM object that can generate real GUIDs or UUIDs, how about just using a long random number instead? It wouldn't be perfect, but it would be far better than what you have right now.

I thought I'd help out a little more by showing you how to generate a true GUID from VBScript.
Function NewGUID()
Dim TypeLib : Set TypeLib = CreateObject("Scriptlet.TypeLib")
NewGUID = CStr(TypeLib.Guid)
End Function
If you use this as your anti-CSRF token then it should be as safe as any other solution out there.

Related

Classic ASP: Session values fail to pass over to popup window

I'm trying to pass values through session from one page to a popup window. But it fail to pass the value. I checked the ISS where Enable Session State is true. I will post the code which I'm working please let me know something I'm missing in it or any other variable settings problem like php.ini
<script language="javascript" type="text/javascript">
function veh(url) {
popupWindow = window.open(url, 'popUpWindow', 'height=300,width=300,left=50,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no, status=yes');
}
</script>
<%
' Define to hold temporary super session
Dim strManu // Manufacture type
strManu = Session("Manu")
Dim objRS
Dim strSQL
Dim strVeh
Set objRS=Server.CreateObject ("ADODB.Recordset")
strSQL="SELECT vl.* FROM veh_tbl vl where vl.manuID= " & strManu
objRS.Open strSQL,objconn
if not objRS.eof then
strVeh=objRS("veh")
Session("Veh")=strVeh
end if
objRS.Close
Set objRS=Nothing
<a href='http://www.example.com/popup.asp' target='_self'
onclick='veh(this.href);return false'><img border='0'src='images/info.jpg'></a>
Popup window
<%
Dim strVal
strVal = Session("Veh")
%>
<FORM name=MyForm>
<% Response.Write "<label class = 'col-sm-4 col-form-label'>" & strVal & "</label>" %>
</FORM>
%>
I'm getting the value from the DB and I'm able to print the string(strVeh) in the same page. I'm not able to pass the same in pop window. It fails to show any error. Anyone please help me to address the issue.
Things I would check:
First, in href='http://www.example.com/popup.asp' does the domain and subdomain match the source page exactly? For example adding or removing the "www" may make a difference.
Are you positive if not objRS.eof then is resolving true? For example try just putting session("test") = "test" somewhere on the page outside of a conditional statement and see if that variable is available in the popup.
Had this issue recently, if I typed in 'https://www.myweb.com/checksession.asp' it would not load/could not see the session variables.
Type in 'https://myweb.com/checksession.asp' (i.e. remove the www.) and it works fine.
So something to bear in mind if referencing from another page/ajax/loading scripts etc.

ASP.Classic Getting value from input to POST parameter

Please excuse me if this question is dumb.
I need to get an input value and pass it in a POST parameter like follow:
SQL = "[proc_Happy]" & Request.Cookies("UserID")& "," & Request.Form("MYINPUTFIELD")
I have tried hardcoding MYINPUTFIELD with (it worked!):
SQL = "[proc_Happy]" & Request.Cookies("UserID")& "," & 54555152
My input in the asp page looks as follow:
<input type="number" name="MYINPUTFIELD " id="MYINPUTFIELD" value="<%=MYINPUTFIELD%>">
Things I have tried:
Getting the value with JS - failed.
Notes:
MYINPUTFIELD is an int
Is your input field in a form, i.e. is it between <form...> and </form> tags? If no, that's your problem right there. If yes, what does the <form...> tag have in it? Does it say method='get'? If yes, then your inputs are being put in the querystring, not the form object. For Request.Form(...) to work, your form needs to say method='post'.
If you need this code to work with both form methods, you can do something like
dim MyInputField
MyInputField = Request.Querystring("MyInputField")
If MyInputField = "" Then MyInputField = Request.Form("MyInputField")
'make the "OMGSQLINJECTION!!1!" people just go away already
'(note to such people: he's using a frigging stored procedure.)
If Not Isnumeric(MyInputField) Then
MyInputField = 0
End If
SQL = "[proc_Happy]" & Request.Cookies("UserID")& "," & MyInputField

internet explorer XMLhttp instead of internet controlls?

I am using vba code to get information out of the web.
Everything is going fine, but it takes soooo long :(
I remember darkly that there is another way to get the information instead of creating an IE Object.
I think I dont need the IE Controlls. I am just loading one link after each other out of an sheet.
How is the other "way" working? Its something like XMLHttp?
Is there a difference for the code? shoudnt be, or?
thanks!
This is what I use:
Function getPage(URLStr As String) As MSHTML.HTMLDocument
Dim oHttpRequest As MSXML2.XMLHTTP60
Set oHttpRequest = New MSXML2.XMLHTTP60
With oHttpRequest
.Open "GET", URLStr, False
.send
End With
Dim oHTMLDoc As MSHTML.HTMLDocument
Set oHTMLDoc = New MSHTML.HTMLDocument
oHTMLDoc.body.innerHTML = oHttpRequest.responseText
Set getPage = oHTMLDoc
End Function
To call the function, use something like this:
Dim oHTMLDoc as MSHTML.HTMLDocument
Set oHTMLDoc = getPage("http://www.example.com")
For this, you'll need to add references to both "Microsoft XML, v6.0" and "Microsoft HTML Object Library", then you can use the MSHTML library to parse through the code as you need.

A generic VBscript function to connect to any database and execute any SQL query

the function should just take connection string and a SQL query as input and it should connect to any database(SQL, ORACLE, SYBASE, MS ACCESS) and execute any query which i have passed as the parameters to the function.
I have written the below function for that task, Can you please check this once and tell me is this correct or pls tell me if i am wrong anywhere.
#
Public Function ConnectDB (strCon, strQuery)
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
objConnection.Open strCon
objRecordSet.Open strQuery,objConnection
objRecordSet.MoveFirst
Do Until objRecordset.EOF
Msgbox "Number of records: " & objRecordset.RecordCount
Msgbox objRecordset(0)
Msgbox objRecordset(1)
objRecordset.MoveNext
Loop
objRecordSet.Close
objConnection.Close
Set objConnection = Nothing
Set objRecordSet = Nothing
End Function
#
Call ConnectDB ("Provider = Microsoft.Jet.OLEDB.4.0; " & _
"Data Source = inventory.mdb","SELECT * FROM EMP ORDER BY EMPName")
UPDATE:
Thank you so much for the replies.
Actually i have been asked to write a function which performs the task of connecting to any database and executing any query(given by user) in that connected database.
I have started to learn VBScript and want to have indepth knowledge of writing functions. Ekkehard horner can you please tell me where can i read to get know all about routines(functions and sub procedure). Presently, i have only the basic idea on routines and i referred MSDN, where they have given only basic information. Please help me where to study more about routines. It is so difficult to write programs without knowing about them correctly.
Hi Sanpaco, below is the class i wrote. Please check it once and let me know the corrections.
I am very new to VBScript.Suggest me ways to improve my programming knowledge.
Class DBCommunicator
Public Function DBConnect(StrCon)
Option Eplicit
Dim oConn
set oConn = CreateObject("ADODB.Connection")
oConn.Open Strcon
Function DBConnect = True
End Function
Public Function QueryDB(StrQuery)
Option Eplicit
Dim oRst, oField
set oRst = CreateObject("ADODB.recordset")
oRst.Open "StrQuery", oConn
Do Until oRst.EOF
For each oField in oRst.Fields
Print oField.Name & " = " & oField.Value
Next
oRst.MoveNext
loop
Public Function DBdisConnect
oRst.close
oConn.close
End Function
End Class
########################################
Option Explicit
Dim strResult
strResult=DBCommunicator.DBConnect("<<Connection String of any database User want to connect>>")
If strResult<>True Then
wscript.echo "DB Connection Failed"
End If
DBCommunicator.QueryDB("Select * from EMP")
DBCommunicator.DBdisConnect
I fixed your code, not sure I agree with it but it seems to work. I don't think VB Script recognizes classes.
Option Explicit
'https://stackoverflow.com/questions/8429313/a-generic-vbscript-function-to-connect-to-any-database-and-execute-any-sql-query
'https://www.connectionstrings.com/microsoft-sql-server-odbc-driver/
Dim oConn, oRst
Public Function DBConnect(StrCon)
set oConn = CreateObject("ADODB.Connection")
oConn.Open Strcon
DBConnect = True
End Function
Public Function DBQuery(StrQuery)
Dim oField
set oRst = CreateObject("ADODB.recordset")
oRst.Open StrQuery, oConn
Do Until oRst.EOF
For each oField in oRst.Fields
wscript.echo oField.Name & " = " & oField.Value
Next
oRst.MoveNext
Loop
End Function
Public Function DBdisConnect
oRst.close
oConn.close
End Function
Dim strResult
strResult=DBConnect("<<Connection String of any database User want to connect>>")
If strResult<>True Then
wscript.echo "DB Connection Failed"
End If
DBQuery("Select * from EMP")
DBdisConnect
A routine (Sub or Function) should do exactly one repeatable/reusable task. Your
Function creates, opens, and closes a connection, creates, uses, and closes a
recordset, and annoys the user with message boxes. If you want to do something
sensible tomorrow, you'll have to write (by copy & paste & modify) another
routine.
A Function should return a value; yours doesn't. A Function should have no
side effects; yours does by doing IO. The work/doings of a routine should
be determined by its parameters alone; yours depends on the default settings/values
for the numerous parameters to the .Open methods you don't provide.
Code should not contain fat; .MoveFirst before a .EOF loop, displaying the
.RecordCount in the loop, and setting object variables to Nothing immediately
before the routine's end is just that. VBScript code should start with "Option
Explicit"; yours obviously doesn't.
While independency of a specific DBMS is attractive when you are learning
or investigating, a professional solution for a real world problem should
be based on the decision for the 'best' DBMS for the task; this will lead
to DBMS specific code using DBMS specific features. Then the switch from
one DBMS to another by changing just the ConnectionString is illusionary.
Database work is either of the "connect-do one thing-disconnect" style of
.Net's ADO or of the "connect on start-do many different things-disconnect on
termination" style of 'classical' ADO. If you indicate, what kind of tasks
you have in mind, I may be willing to append to this answer.
You might consider creating a DatabaseCommunicator class that does separate database functions (Connect, ExecuteQuery, Disconnect) instead of trying to do everything with one method. Also if you are wanting to use different types of providers dynamically then you would need to validate the query format to make sure it uses the correct syntax for whatever provider you are using.
I would be very interested in seeing how you accomplish this task should you take it on.

List audio input devices - VBA

I have a bit of a complex Access Database that I need to do some audio recording with. I have nearly everything working using outside solutions but I am forced to select my input device from within Access.
All that I need is some way to get a collection of devices or something from Windows and I can take it from there. http://www.vbmonster.com/Uwe/Forum.aspx/vb/32848/listing-all-audio-devices does something close to what I am looking for except that is the output instead of the input. I know that there will be no extremely easy way to accomplish this but I know it is possible, I just can't seem to find how.
The code you linked creates a SWbemObjectSet, then lists properties of its members (sound devices). From what I can tell, you want that object but don't want to list the properties ("output").
If that is correct, create a function which strips away the output statements and just returns the SWbemObjectSet object.
Public Function getSoundDevices(Optional strComputer As String = ".") As Object
Const cstrQuery As String = "Select * from Win32_SoundDevice"
Dim objWMIService As Object 'TypeName = SWbemServicesEx '
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set getSoundDevices = objWMIService.ExecQuery(cstrQuery, , 48)
Set objWMIService = Nothing
End Function
Then call the function to use the SWbemObjectSet as input for your other code.
Public Sub test_getSoundDevices()
Dim objSoundDevices As Object 'TypeName = SWbemObjectSet '
Dim objDevice As Object 'TypeName = SWbemObjectEx '
Set objSoundDevices = getSoundDevices()
For Each objDevice In objSoundDevices
'* do what you want for each sound device here *'
Debug.Print "ProductName: " & objDevice.ProductName
Next objDevice
Set objDevice = Nothing
Set objSoundDevices = Nothing
End Sub
Hmm, not the easiest question :-) I think you indeed need to invoke a native function.
Maby something like this:
http://msdn.microsoft.com/en-us/library/ms645598(v=vs.85).aspx
VB implementation in the bottom.
Good luck!

Resources