I know a little about SQL injections and URL decode, but can someone who's more of an expert than me on this matter take a look at the following string and tell me what exactly it's trying to do?
Some kid from Beijing a couple weeks ago tried a number of injections like the one below.
%27%20and%20char(124)%2Buser%2Bchar(124)=0%20and%20%27%27=%27
It's making a guess about the sort of SQL statement that the form data is being substituted into, and assuming that it will be poorly sanitised at some step along the road. Consider a program talking to an SQL server (Cish code purely for example):
fprintf(sql_connection, "SELECT foo,bar FROM users WHERE user='%s';");
However, with the above string, the SQL server sees:
SELECT foo,bar FROM users WHERE user='' and char(124)+user+char(124)=0 and ''='';
Whoops! That wasn't what you intended. What happens next depends on the database back-end and whether or not you've got verbose error reporting turned on.
It's quite common for lazy web developers to enable verbose error reporting unconditionally for all clients and to not turn it off. (Moral: only enable detailed error reporting for a very tight trusted network, if at all.) Such an error report typically contains some useful information about the structure of the database which the attacker can use to figure out where to go next.
Now consider the username '; DESCRIBE TABLE users; SELECT 1 FROM users WHERE 'a'='. And so it goes on... There are a few different strategies here depending on exactly how the data comes out. SQL injection toolkits exist which can automate this process and attempt to automatically dump out the entire contents of a database via an unsecured web interface. Rafal Los's blog post contains a little more technical insight.
You're not limited to the theft of data, either; if you can insert arbitrary SQL, well, the obligatory xkcd reference illustrates it better than I can.
You'll find detailed info here:
http://blogs.technet.com/b/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx
These lines are double-encoded -- the
first set of encoded characters, which
would be translated by IIS, are
denoted by %XX. For example, %20 is a
space. The second set aren't meant to
be translated until they get to the
SQL Server and they use the char(xxx)
function in SQL.
' and char(124)+user+char(124)=0 and ''='
that's strange..however, make sure you escape strings so there will be no sql injections
Other people have covered what's going on, so I'm going to take a moment to get on my high-horse and strongly suggest that if you're not already (I suspect not from a comment below) that you use parameterized queries. They literally make you immune to SQL injection because they cause parameters and the query to be transmitted completely separately. There's also potential performance benefits, yadda yadda, etc.
But seriously, do it.
Related
I'm after a DB Comparison tool for SQL Server that allows me to do the following:
Schedule a comparison to happen on a recurring schedule
Email me the results (in a nice readable format and not the generated script)
Allow me to exclude/include certain object names (for example exclude table names containing %test%. That's not a real example but there is a good reason why that would come in useful.)
As well as the obvious:
Have the usual options for ignoring things like comments, identity seeds etc
Options for selecting different types of objects
If it was free or at least didn't cost a forture that would be an extra bonus of course.
I have tried out RedGate's SQL Compare and also the built-in DB Comparison in Visual Studio but neither seem able to do the first 3 points above. I also looked at other tools recommended in various threads on here but again they don't mention in their features the 3 points above.
One option I found is RedGate's SQL Comparison SDK with which I think I could write something to do what I want.
I just wanted to investigate tools that might do all of the above out of the box.
Thank you!
SQL Compare Pro comes with a command line, which will be easier to set up than the SDK. If you call this via the Windows Scheduler or in an Agent Job you can achieve what you're looking for.
An example of how to invoke the command line from Powershell it can be found here:
http://www.simple-talk.com/sql/database-administration/auditing-ddl-changes-in-sql-server-databases/
This article also covers how to send an email in Powershell. SQL Compare can also be passed a filter using the /filter switch to exclude objects based on various rules.
http://www.red-gate.com/supportcenter/Content/SQL_Compare/help/10.0/sc_cl_Switches_in_the_cl
Do please email support#red-gate.com should you have trouble getting this working.
I don't think any tool would do all of this out of the box. Have you had a chance to look at
sp_CompareDB. I had a similar requirement and ended up writing my own routine based on the same.
http://www.sql-server-performance.com/2001/database-comparison-sp/
Last night one of our SQL servers developed some major problems and after a colleague stopped, started, and all the usual things it started checking and rebuilding databases and is now running an extended stored procedure called "xp_qv".
The internet seems to be very short of information on what this procedure does or anythign like that so I was hoping somebody here might be able to help.
I should add that I assume it is meant to be running so the question isn't "Can I stop it" or anything like that, its just curiosity in what it is doing in the hope that it will help determine how long before things are usable again...
This is the only information I could find..
xp_qv, hosted in xpsqlbot.dll is a
wrapper around functionality in
sqlboot.dll, which returns information
about the SKU type, licensing etc It
is not documented that is why you can
not find a reference.
I created a database for tracking metrics, with some automation tricks (email, .doc,.ppt presentations, etc) with a very large Main-table, and lots of forms/GUI. This is the first time I have ever I worried about an MDE/front-end for the thing. So if you would be so kind to answer a few questions, or offer any advice, it would be greatly appreciated (I would hate for all this work to not be utilized).
What is the first thing I need to do? It the 2000 version that must be converted to 03 to create the MDE, but does that get done before I use the database splitter?
Will the amount of objects in the database effect the ability to do this? I have something like 80 forms, 70 queries, 20+ macros, 12 tables, etc...but does the amount of objects prevent some of this from working well once the front end is there?
when i split the database, can I continue to work/make changes and such on the "back end", and have those changes directly effect the front end?
These may be some basic questions, but I don't know the answer so.....Thanks!
Here is my 2 ยข.
Question 1 - I have never used the database splitter as I feel I have more control doing it manually. If you do it manually you can do it to a version that does not have a database splitter. But if you do use the splitter then--yes--you will have to upgrade to a version that has a splitter before doing it.
To do it manually here are the steps.
Backup everything.
Create a copy of your file into the same directory. So if you have an MyApp.MDB create a copy into the same directory with a new name, such as MyAppDATA.mdb.
Open the new DATA file (MyAppDATA.mdb) and delete all of the objects EXCEPT the TABLES.
Open the App file (MyApp.mdb) and delete all of the tables.
Also in MyApp.mdb...go to the File/Get External Data/Link Tables menu to link the tables in MyAppDATA.mdb to MyApp.mdb. Select All and create the links.
That should do it. And if you screw up you made a backup...right?
A couple of tips and gotchas...be sure that you go to Tools/Options and that you are NOT showing System and Hidden tables. You just don't want to delete system tables from MyApp. Another way to do it is do NOT delete tables that start with MSys or USys.
Question 2 - Does not matter how many object you have. In fact you don't have that many objects anyway.
Question 3 - Yes...you will make backend changes in MyAppData.mdb and when you open MyApp.mdb those changes will auto-magically be there to see and query against etc. (In the query designer you may need to save/close/reopen to see new fields if you made the mod while in the query). The EXCEPTION to that is New Tables You will have to use the File/Get External Data/Link Tables option to create links to new tables.
One thing to remember (and that I hope you already realize) is that the one downside of splitting the database is that when you deploy the front end file that usually the relative path to the data will vary from machine to machine and there is no automatic re-linking of tables in access. If your target clients have full access you can always use Tools/Database Utilities/Linked Table Manager to refresh the links to the right location. If you can't do that then you will have to do one of the following:
1. Write code that does the automatic re-linking for you. Basically it will check the links...if invalid it will prompt the user for the data location (or look it up in an INI file) and re-link the tables.
2. Always deploy your app to the same location on all machines. If you have commercial visions for your application this won't work...I mention it for academic reasons. It might be doable for a limited deployment where you have a lot of control over file placement on each machine.
3. Put the Data file (MyAppDATA.mdb) onto a network share and link the table across the network using a drive mapping or UNC (\myserver\mydata\ApplicationData\MyAppData.mdb). The latter is preferred but both of them run the same risks as number two.
Seth
PS This answer assumes Access 2003.
PPS If you have commercial visions for your application then the table linking has got to be REALLY robust.
PPPS I agree with the commenter that you may want to take the plunge and do SQL if it is in your skill set.
One thing that hasn't been discussed, and that's the issue of whether the compile to MDE could fail. Basically, if your code compiles in your front-end MDB, it will convert to an MDE. But I've noticed that lots of people never compile.
Some hints for keeping your VBA code in good shape:
in VBE options, turn off COMPILE ON DEMAND.
add the COMPILE button to your standard VBE toolbar and USE IT OFTEN.
periodically, backup your MDB and decompile/recompile it.
Also, remember that you must keep the MDB source, as the VBA code is not editable in an MDE and not recoverable by any good method.
EDIT:
Steps for a decompile:
backup your MDB.
start an instance of Access with the /decompile commandline argument. For, instance, I have a shortcut on my deskstop that has this as the target:
"C:\Program Files\Microsoft Office\OFFICE11\MSACCESS.EXE" /decompile
having opened that instance of Access, open the MDB you want to decompile. You will see nothing happen. DO NOTHING FURTHER IN THIS INSTANCE OF ACCESS -- close this instance of Access (the reason for this is that Michael Kaplan, who knows a thing or two about this, recommended that you never do any work in an Access instance opened with the decompile switch because he said there was no guarantee that the Access application code executed under those circumstances in a way that was fully safe for all kinds of Access work).
open the just-decompiled MDB holding down the shift key (you want to be sure that startup routines don't run because that would likely recompile the product before you've finished your cleanup) and compact the MDB (holding down the shift key again).
open the code editor and compile the project (DEBUG -> COMPILE [db name] for those who haven't step #2 in my original compiling instructions at the top of the post before the edit).
compact the MDB (doesn't matter if you bypass startup, since it's already fully compiled).
Why so many steps?
Because the purpose of the decompile is to get rid of the compiled p-code in order to start afresh from the canonical VBA code. Following the steps above insures that you have completely cleared the data pages storing the compiled code before you recompile. The reason for this is that without the compact step after the decompile, under some very rare circumstances, the code can behave strangely. I can't imagine that the old discarded p-code is being used again, but there's something about the pointers between the canonical code and the compiled code that apparently doesn't get completely flushed by a decompile without a compact.
This would be a comment to Seth's answer, but my rep isn't high enough to comment yet.
Seth did a great job answering your questions, I just wanted to add a bit more to part #1 about using the Database Splitter. The Database Splitter in the Tools menu works fine. Doing it manually is alright too, but it's a whole lot faster and easier to use the Database Splitter. I've used it a dozen times and never encountered any issues after using it.
http://www.databasedev.co.uk/split_a_database.html has a decent page about some of the pros, cons of splitting your database.
http://www.accessmvp.com/TWickerath/articles/multiuser.htm also has some good info when dealing with a split database in a multi-user environment.
Seth gave you a very good answer. But I'll add a few comments.
The number of objects only becomes relevant when you get close to about 1000 forms, reports and modules which have code. There's a limit about there. If you do get that message when trying to make an MDE then you almost certainly have a code error and need to compile to find the error
Another resource is "Splitting your app into a front end and back end Tips"
See the Auto FE Updater downloads page to make the process of distributing new FEs relatively painless.. The utility also supports Terminal Server/Citrix quite nicely.
I have been getting a number of attacks on my website lately, with a User-Agent of NV32ts.
They all are some variation of the following injection attacks against a querystring variable (where 99999 represents a valid querystring value, the attack is appended to the value):
(For convenience I have urldecoded the following attacks)
999999 And char(124)+(Select Cast(Count(1) as varchar(8000))+char(124) From [sysobjects] Where 1=1)>0
or
999999' And char(124)+(Select Cast(Count(1) as varchar(8000))+char(124) From [sysobjects] Where 1=1)>0 and ''='
or
999999' And char(124)+(Select Cast(Count(1) as varchar(8000))+char(124) From [sysobjects] Where 1=1)>0 and ''='
I believe that sysobjects has something to do with the Sql Server master database, but I can't figure out what they are trying to accomplish.
Edit:
I have now seen these same things with two different user agents:
NV32ts
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; WWTClient2)
I read this one two ways, but I'm not 100% sure which:
At this point they're just fishing. The script is looking for web sites that have both open injection vulnerabilities and access to the sysobjects table in sql server. That table will provide a list of all tables and columns (and their types) in the database. If the page actually returns a result rather than throwing an error, the script will log that for a future more detailed attack. You'll eventually end up with malicious javascript code appended to every text (varchar, nvarchar, char, nchar, text) column of every row of every table in the entire db. I think this is the more-likely option.
It creates an expression that will always return true, perhaps allowing them bypass your authentication system. This seems less likely, because the sysobjects reference makes it needlessly complex. Also: they used And rather than Or.
I believe what they are trying to figure out here is if your application is vulnerable to SQL Injection.
The Char(124) translates to the | character which forces the whole query result to be seen as the result of the query with two pipes attached. So you end up with the number of tables in your database with two pipes attached (ex. |1428|). Which when compared to 0 in the > 0 causes an error because |1428| is not an int.
So if your application is open to SQL Injection they now know it (because the valid parameter value caused the application to err). They might also know that you have bad error handling if they SQL database error bubbles up to the top. If you do have bad error handling they also know how many tables you have (not sure what good that does them but the more information the better).
A lot of SQL injection attempts are really meant to cause your application to fail in order to know that you are vulnerable. If you do handle errors well they may then attempt to blind SQL inject you.
Check out this to see that in detail.
I hope that you are not vulnerable, and if you are good luck!
HP has a free tool you can run to check if your site (or any site) has SQL Injection vulnerabilities called sdrawlr.
You can download it here:
I have a couple of questions regarding VBScript and ASP Classic:
What is the preferred way to access an MS SQL Server database in VBScript/ASP?
What are best practices in regards to separating model from view from controller?
Any other things I should know about either VBScript or ASP?
If you haven't noticed, I'm new at VBScript coding. I realize numbers 2 & 3 are kind of giant "black hole" questions that are overly general, so don't think that I'm expecting to learn everything there is to know about those two questions from here.
ADO is an excellent way to access a database in VBScript/Classic ASP.
Dim db: Set db = Server.CreateObject("ADODB.Connection")
db.Open "yourconnectionstring -> see connectionstrings.com"
Dim rs: Set rs = db.Execute("SELECT firstName from Employees")
While Not rs.EOF
Response.Write rs("firstName")
rs.MoveNext
Wend
rs.Close
More info here: http://www.technowledgebase.com/2007/06/12/vbscript-how-to-create-an-ado-connection-and-run-a-query/
One caveat is that if you are returning a MEMO field in a recordset, be sure you only select ONE MEMO field at a time, and make sure it is the LAST column in your query. Otherwise you will run into problems.
(Reference: http://lists.evolt.org/archive/Week-of-Mon-20040329/157305.html )
I had to walk away from my PC when I saw the first answer, and am still distressed that it has been approved by so many people. It's an appalling example of the very worst kind of ASP code, the kind that would ensure your site is SQL-injectable and, if you continue using this code across the site, hackable within an inch of its life.
This is NOT the kind of code you should be giving to someone new to ASP coding as they will think it is the professional way of coding in the language!
NEVER reveal a connection string in your code as it contains the username and password to your database. Use a UDL file instead, or at the very least a constant that can be declared elsewhere and used across the site.
There is no longer any good excuse for using inline SQL for any operation in a web environment. Use a stored procedure -- the security benefits cannot be stressed enough. If you really can't do that then look at inline parameters as a second-best option... Inline SQL will leave your site wide open to SQL injection, malware injection and the rest.
Late declaration of variables can lead to sloppy coding. Use "option explicit" and declare variables at the top of the function. This is best practice rather than a real WTF, but it's best to start as you mean to go on.
No hints to the database as to what type of connection this is -- is it for reading only, or will the user be updating records? The connection can be optimised and the database can handle locking very efficiently if effectively told what to expect.
The database connection is not closed after use, and the recordset object isn't fully destroyed.
ASP is still a strong language, despite many folks suggesting moving to .NET -- with good coding practices an ASP site can be written that is easy to maintain, scaleable and fast, but you HAVE to make sure you use every method available to make your code efficient, you HAVE to maintain good coding practices and a little forethought. A good editor will help too, my preference being for PrimalScript which I find more helpful to an ASP coder than any of the latest MS products which seem to be very .NET-centric.
Also, where is a "MEMO" field from? Is this Access nomenclature, or maybe MySQL? I ask as such fields have been called TEXT or NTEXT fields in MS-SQL for a decade.
Remember to program into the language rather than program in it. Just because you're using a limited tool set doesn't mean you have to program like it's 1999.
I agree with JasonS about classes. It's true you can't do things like inheritance but you can easily fake it
Class Dog
Private Parent
Private Sub Class_Initialize()
Set Parent = New Animal
End Sub
Public Function Walk()
Walk = Parent.Walk
End Function
Public Function Bark()
Response.Write("Woof! Woof!")
End Function
End Class
In my projects an ASP page will have the following:
INC-APP-CommonIncludes.asp - This includes stuff like my general libraries (Database Access, file functions, etc) and sets up security and includes any configuration files (like connection strings, directory locations, etc) and common classes (User, Permission, etc) and is included in every page.
Modules/ModuleName/page.vb.asp - Kind of like a code behind page. Includes page specific BO, BLL and DAL classes and sets up the data required for the page/receives submitted form data, etc
Modules/ModuleName/Display/INC-DIS-Page.asp - Displays the data set up in page.vb.asp.
Echoing some ideas and adding a few of my own:
1) Best way to access the database would to abstract that away into a COM component of some sort that you access from VBScript.
2) If you really wanted to you could write the controller in VBScript and then access that in the page. It would resemble a Page Controller pattern and not a Front Controller that you would see in ASP.NET MVC or MonoRail
3) Why are you doing this to yourself? Most of the tooling required to do this kind of work isn't even available anymore.
AXE - Asp Xtreme Evolution is a MVC framework for ASP classic
There are some attempts at making test frameworks for asp:
aspUnit is good, but no longer maintained.
I saw a sample on how to make your own one a few months back.
The example used nUnit to call functions against the website for automatic testing.
I think i got it off here (my line is borked so I can't check)
On number 2, I think you have a few options...
1) You can use COM components developed in VB6 or the like to separate some of your business logic from your UI.
2) You can create classes in VBScript. There is no concept of inheritance and other more advanced features are missing from the implementation, but you can encapsulate logic in classes that helps reduce the spagehtti-ness of your app. Check out this: https://web.archive.org/web/20210505200200/http://www.4guysfromrolla.com/webtech/092399-1.shtml
I agree with #Cirieno, that the selected answer would not be wise to use in production code, for all of the reasons he mentions. That said, if you have just a little experience, this answer is a good starting point as to the basics.
In my ASP experience, I preferred to write my database access layer using VB, compiling down to a DLL and referencing the DLL via VBScript. Tough to debug directly through ASP, but it was a nice way to encapsulate all data access code away from the ASP code.
way way back in the day when VBScript/ASP were still ok
I worked in a utility company with a very mixed DB envrionment, I used to swear by this website: http://www.connectionstrings.com/
#michealpryor got it right
I've been stuck building on ASP, and I feel your pain.
1) The best way to query against SQL Server is with parameterized queries; this will help prevent against SQL injection attacks.
Tutorial (not my blog):
http://www.nomadpete.com/2007/03/23/classic-asp-which-is-still-alive-and-parametised-queries/
2) I haven't seen anything regarding MVC specifically geared towards ASP, but I'm definitely interested because it's something I'm having a tough time wrapping my head around. I generally try to at least contain things which are view-like and things which are controller-like in separate functions. I suppose you could possibly write code in separate files and then use server side includes to join them all back together.
3) You're probably coming from a language which has more functionality built in. At first, some things may appear to be missing, but it's often just a matter of writing a lot more lines of code than you're used to.
Also for database access I have a set of functions - GetSingleRecord, GetRecordset and UpdateDatabase which has similar function to what Michael mentions above