SQL Injection or Server.HTMLEncode or both? Classic ASP - security

People say to prevent SQL Injection, you can do one of the following (amongst other things):
Prepare statements (parameterized)
Stored procedures
Escaping user input
I have done item 1, preparing my statements, but I'm now wondering if I should escape all user input as well. Is this a waste of time seeming as I have prepared statements or will this double my chances of prevention?

It's usually a waste of time to escape your input on top of using parametrized statements. If you are using a database "driver" from the database vendor and you are only using parametrized
statements without doing things like SQL String concatenation or trying to parametrize the actual SQL syntax, instead of just providing variable values, then you are already as safe as you can be.
To sum it up, your best option is to trust the database vendor to know how to escape values inside their own SQL implementation instead of trying to roll your own encoder, which for a lot of DBs out there can be a lot more work then you think.
If on top of this you want additional protection you can try using a SQL Monitoring Solution. There are a few available that can spot out-of-the-ordinary SQL queries and block/flag them, or just try to learn your default app behavior and block everything else. Obviously your mileage may vary with these based on your setup and use-cases.

Certainly the first step to prevent SQL Injection attacks is to always use parameterised queries, never concatenate client supplied text into a SQL string. The use of stored procedures is irrelevant once you have taken the step to parameterise.
However there is a secondary source of SQL injection where SQL code itself (usually in an SP) will have to compose some SQL which is then EXEC'd. Hence its still possible to be vunerable to injection even though your ASP code is always using parameterised queries. If you can be certain that none of your SQL does that and will never do that then you are fairly safe from SQL Injection. Depending on what you are doing and what version to SQL Server you are using there are occasions where SQL compositing SQL is unavoidable.
With the above in mind a robust approach may require that your code examines incoming string data for patterns of SQL. This can be fairly intense work because attackers can get quite sophisticated in avoiding SQL pattern detection. Even if you feel the SQL you are using is not vunerable it useful to be able to detect such attempts even if they fail. Being able to pick that up and record additional information about the HTTP requests carrying the attempt is good.
Escaping is the most robust approach, in that case though all the code that uses the data in you database must understand the escaping mechanim and be able to unescape the data to make use of it. Imagine a Server-side report generating tool for example, would need to unescape database fields before including them in reports.
Server.HTMLEncode prevents a different form of Injection. Without it an attacker could inject HTML (include javascript) into the output of your site. For example, imagine a shop front application that allowed customers to review products for other customers to read. A malicious "customer" could inject some HTML that might allow them to gather information about other real customers who read their "review" of a popular product.
Hence always use Server.HTMLEncode on all string data retrieved from a database.

Back in the day when I had to do classic ASP, I used both methods 2 and 3. I liked the performance of stored procs better and it helps to prevent SQL injection. I also used a standard set of includes to filter(escape) user input. To be truly safe, don't use classic ASP, but if you have to, I would do all three.

First, on the injections in general:
Both latter 2 has nothing to do with injection actually.
And the former doesn't cover all the possible issues.
Prepared statements are okay until you have to deal with identifiers.
Stored provedures are vulnerable to injections as well. It is not an option at all.
"escaping" "user input" is most funny of them all.
First, I suppose, "escaping" is intended for the strings only, not whatever "user input". Escaping all other types is quite useless and will protect nothing.
Next, speaking of strings, you have to escape them all, not only coming from the user input.
Finally - no, you don't have to use whatever escaping if you are using prepared statements
Now to your question.
As you may notice, HTMLEncode doesn't contain a word "SQL" in it. One may persume then, that Server.HTMLEncode has absolutely nothing to do with SQL injections.
It is more like another attack prevention, called XSS. Here it seems a more appropriate action and indeed should be used on the untrusted user input.
So, you may use Server.HTMLEncode along with prepared statements. But just remember that it's completely different attacks prevention.
You may also consider to use HTMLEncode before actual HTML output, not at the time of storing data.

Related

SQL Injection assistance required

I am trying to understand the below injection and what it is trying to do. What is it trying to get? The only portion I understand is the union and select part, but the full injection I am unsure of and need help understanding.
action=&aid=1&_FILES%5Btype%5D%5Btmp_name%5D=%5C%27%20or%20mid=#%60%5C%27%60%20/!50000union//!50000select/1,2,3,(select%20CONCAT(0x7c,userid,0x7c,pwd)+from+%60%23#__admin%60%20limit+0,1),5,6,7,8,9%23#%60%5C%27%60+&_FILES%5Btype%5D%5Bname%5D=1.jpg&_FILES%5Btype%5D%5Btype%5D=application/octet-stream&_FILES%5Btype%5D%5Bsize%5D=4294
Well, first we can url decode the string:
action=
&aid=1
&_FILES[type][tmp_name]=\' or mid=#`\'`/!50000union//!50000select/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd) from `##__admin` limit 0,1),5,6,7,8,9##`\'`
&_FILES[type][name]=1.jpg
&_FILES[type][type]=application/octet-stream
&_FILES[type][size]=4294
One of these parameters sticks out as pretty suspicious.
[tmp_name]=\' OR mid=#`\'`
/!50000union/
/!50000select/1,2,3,
(select CONCAT(0x7c,userid,0x7c,pwd)
from `##__admin`
limit 0,1)
,5,6,7,8,9##`\'`
In plain english, it's injecting a select query to get usernames and passwords in a format like 0x7c<user>0x7c<password> from the ##__admin table (which, according to #DCoder is likely a placeholder for the actual table where these values would be kept) and appending it to your original select.
The !50000 stuff is for bypassing your web application firewall (if you have one). If you don't, then it may just be a bot or automated attempt. Or someone following a script to see what works. The numbers aren't really useful - it may be for evading a firewall or just for debugging purposes for the attacker to see how the output looks. It's hard to tell without being able to run it.
Here's what the SQL the attacker is trying to run would look like in 'plain SQL':
select
userid,
pwd
from
`##__admin`
Do you have a table like this? When you go to this url for your site, does it dump the user table? If not, then you may not even have a problem and it is just an automated scan. You may still have issues with SQL injection, even if it doesn't work, but having this in your logs is not evidence of a breach... it's definitely a red flag though.
It's adding extra columns to the result recordset, with user/pwd information. So in essence, the user wants to collect user accounts he or she wants to abuse.
It have to be noted that SQL injection (if any) is made possible by another vulnerability.
It is clear that this application is depending (or at least it is believed by the malicious user) on the some sort of homebrewed implementation of register_globals. A worst implementation ever.
To make this code work, the application have to take GET variables, and blindly convert them in global variables, making $_FILE array to appear not from internal process but from mere GET request.

What Does /**/or/**/ Mean?

We've logged get requests where someone tried to add /**/or/**/ to the query string.
What does it mean, where can it do damage and what should I look out for in my code?
Edit
Specifically /**/or/**/1=##version)-- - what would that be targeting?
It's almost certainly an attempt at a SQL Injection Attack or something very similar. It's easiest to think (and read) about this kind of vulnerability in terms of SQL, even if it's a slightly different attack vector in your case.
The idea is that if you've got SQL of this kind:
"SELECT User from USERS where UserName =" + user + " AND PASSWORD = " + password
then inserting values like the one you've seen directly into the SQL can cause the query to mean something entirely different (and typically laxer) than you expect. Normally SQL injection attacks contain single quotes though, to terminate text values within SQL. Are you sure the attacks you've seen don't have single quotes?
If you use parameterized SQL throughout your application (and no dynamic SQL within your database), and never try to use incoming user-specified values as "code" of any kind, you should be okay.
I suspect in your case it may not be SQL that the attacker expects to use to penetrate your security; it may well be Javascript. The idea is the same though: if you use any user input as "code" in some form, e.g. by building a string mixing that with predefined code, then execute that code, you're leaving yourself vulnerable to attack. Always treat code as code (under your control) and data as data.

Code generation against Sprocs?

I'm trying to understand choices for code generation tools/ORM tools and discover what solution will best meet the requirements that I have and the limitations present.
I'm creating a foundational solution to be used for new projects. It consists of ASP.NET MVC 3.0, layers for business logic and data access. The data access layer will need to go against Oracle for now, and then switch to SQL this year as the db migration is finished.
From a DTO standpoint mapping to custom types in the solution, what ORM/code generation tool will work with creating my needed code but can ONLY access Stored Procs in Oracle and SQL.?
Meaning, I need to generate the custom objects that are the artifacts from and being pushed to the stored procedures as the parameters, I don't need to generate the sprocs themselves, they already exist. I'm looking for the representation of what the sproc needs and gives back to be generated into DTOs. In some cases I can go against views and generate DTOs. I'm assuming most tools already do this. But for 90% of the time, I don't have access directly to any tables or views, only stored procs.
Does this make sense?
ORMs are best at mapping objects to tables (and/or views), not mapping objects to sprocs.
Very few tools can do automated code generation against whatever output a sproc may generate, depending on the complexity of the sproc. It's much more straight-forward to code generate the input to a sproc as that is generally well defined and clear.
I would say if you are stuck with sprocs, your options for using third party code to help reduce your development and maintenance time are severely limited.
I believe either LinqToSql or EntityFramework (or both?) are capable of some magic with regards to SQL Server to try to mostly automatically figure out what a sproc may be returning. I don't think it works all the time, it's just sophisticated guess work and I seriously doubt it would work with Oracle. I am not aware of anything else software-wise that even attempts to figure out what a sproc may return.
A sproc can return multiple diverse record sets that can be built dynamically by the sproc depending on the input and data in the database. A technical solution to automatically anticipating sproc output seems like it would require the following:
A static set of underlying data in the database
The ability to pass all possible inputs to the sproc and execute the sproc without any negative impact or side effects
That would give you a static set of possible outputs for any given valid input. A small change in the data in the database could invalidate everything.
If I recall correctly, the magic Microsoft did was something like calling the sproc passing NULL for all input parameters and assuming the output is always exactly the first recordset that comes back from the database. That is clearly an incomplete solution to the problem, but in simple cases it appears to be magic because it can work very well some of the time.

Restrict semicolon to prevent SQL injection?

I've seen that SQL injection strings are often constructed like this:
' ; DROP DATABASE db --
Therefore, if I disallow the use of semicolons in my application's inputs, does this 100% prevent any SQL injection attack?
Use parameterized queries (or stored procedures) and avoid dynamic SQL like the plague.
I suggest using built in library functions instead of trying to write your own anti-injection code.
A naive implementation will strip out ; even if it should be used (say as part of a passed in VARCHAR or CHAR parameter, where it is legal). You will end up having to write your own SQL parser in order to accept/reject queries.
You can read here more about dynamic SQL and the problems it presents (and solves).
No it does not prevent sql injection attacks. Any time you're dynamically constructing SQL either in the client side, or with the EXEC inside a stored proc, you are at risk.
Parameterized queries are the preferred way to get your input into query.
No, it doesn’t. You just showed one example of an SQL injection. But there are far more, all depending on the context you insert the data into.
Besided that, it’s not the semicolon that causes this issue but the ' that ends the string declaration prematurely. Encode your input data properly to prevent SQL injection.
It MAY stop from injecting a secondary DDL statement like your drop since they'll likely create a syntax error within a select, but it won't stop statements like this:
Return more data than intended
' or 1=1
Delete with output
' or 1 in (select * from (delete someOtherTable OUTPUT DELETED.* ) a)
Injection attacks revolve around ANY manipulation of the intended SQL statement, not just termination of that statement and injecting a second statement.
Injection Attacks Come from Un-sanitized User Input
It's important, however, to not conflate a SQL injection attack entirely with dynamic/inline sql. SQL injection attacks come from UN-SANITIZED USER INPUT used in dynamic sql. You can "build" a query with no problem as long as the components of that query all come from sources that you trust. For example we use schemas to hold custom structures...
$"select * from {customSchemaName}.EmployeeExtension where id=#id and clientid=#clientId"
The above is still a parameterized query from an input point of view, but the schema name is an internal system lookup that no interface has access to.
I make the case for inline/dynamic sql here:
https://dba.stackexchange.com/a/239571/9798
The best way to avoid SQL injection is to avoid string concatenation of user supplied data. This is best accomplished by either using stored procedures or using parameterized queries.
No, don't focus on semicolons. Focus on the way you put user input in the sql query - usually in quotes - and then focus on the quotes. Also don't forget when you work with regexp in sql that they need slightly different escaping procedure.
it will depend on a variety of things (which queries, etc). you should use prepared statements for this

What are some general best practices for input validation?

What are some best pratices associated with use of IRIs to prevent character missrepresentation, spoofing, or character injection?
There is no one silver bullet for preventing all attacks that involve injecting control characters. Vulnerabilities are highly dependent on how the data is being used. For instance xss uses the control characters <> where as SQL Injection uses the control characters '"\, to mix both of these filters does not make sense.
One can use a collection of Regular Expressions to insure that data is valid before it is used. A specific regular expression can be used to prevent a specific vulnerability on a function by function basis. Input validation goes beyond the realm of security and is often required for the program to work properly.
Regex's are not always the best way to get the job done. For instance if you are using the mysql library there should be the function call mysql_real_escape_string() which insures that all control characters that mysql recognizes are properly escaped. It is in your best interest to use this function instead of attempting to write your own security system, re-inventing the wheel is bad engineering and can be catastrophic when it comes to security systems.

Resources