Preventing SQL Injection in non-executed SQL - c#

I'm calling a web service and passing it a string of dynamically-generated SQL. This string contains user input. It is currently being built using simple string concatenation, and is therefore vulnerable to a SQL injection attack. I cannot use the normal parameterized SQL solutions, because I'm not executing the command from my application.
My first attempt was to build a parameterized SqlCommand object. However, there does not appear to be any way to extract the final SQL statement. My second attempt was to use sp_executesql, but that seems to have the same problem as my original code: concatenating a SQL command together with user input.
So, how can I generate the SQL without resorting to writing my own input sanitization logic (i.e. .Replace("'", "''")? Is there a built-in class or a good third-party library available?

As I understand the question... how can you generate the SQL without resorting to writing my own input sanitization logic. There are several sql injection mitigation techniques to consider using.
Some of these are security-based on the back-end and others are business and application development rules enforced by the database engine.
Back-End Security: Always apply the “Least Privilege” rule: set up low-privileged database accounts
for applications that access the DBMS.
Server Side Sanitation: On the server side. validate user-supplied data – as well as any data obtained from a potentially unsafe sourceClient-side input validation can be
useful
Client-Side: Do not return SQL error messages to users as they contain information useful for
attackers, such as the query or details about the targeted tables or even their content.
This can be easily prevented in Java using exception handling.
Client-Side: Encode text input fields likely to contain problematic characters into an
alphanumeric version using a two-way function such as Base64.
Client-Side: Be proactive in writing the code to prevent SQL injection. Filter all input data via a 2-step process. First, apply white-list filtering at user
input collection (e.g., web forms): allow only field-relevant characters, string formats
and data types; restrict string length. Then, black-list filtering or escaping should be
applied in the data access layer before generating SQL queries: escape SQL metacharacters
and keywords/operators.
Client or middle-tier side.: Validate dynamically-generated database object names (e.g. table names) with strict white-list filtering.
Client-Side Avoid quoted/delimited identifiers as they significantly complicate all whitelisting,
black-listing and escaping efforts.
Development: Enforce process to have developers a safe API which will take care of security and avoid SQL Injection. Do this instead of relying on developers to implement complex defensive coding techniques.
API: Develop an API or middel tier that analyzes the database schema at compile time
and writes code for a custom set of SQL query construction classes (which then
integrate into the IDE and are directly called by developers to build SQL queries).
The result is a tree-like structure based on a generic template, mapping the
possible variations of SQL queries according to tables and columns definition.
There are 3 main types of classes: SQL statements, table columns and where
conditions. These classes have strong-typed methods mapping the data types in the
database schema. Attack surface is reduced. The proposed API would not execute queries as you specified in your question, it only generates the SQL. The proposed API would check data types against its mappings, upon input value submission. Second, the query would be pre-compiled by the
DBMS-specific driver using JDBC’s PreparedStatement interface with binded
variables. Any error in either step will prevent the query’s execution.
The proposed API design used by developers would address server-side validation , SQL error interception. Strong typing are directly enforced, while text input encoding and 2-step input validation are not needed , as dynamic input is injected through a separate protected data
channel (binded variables) via the PreparedStatement interface. Object names are not inputted by the user and are routinely validated. A low-privileged database account should however still be provided to the proposed API.
In the proposed API, Data input entry points do not need to be identified as protection is applied right before database interaction. Segmented queries are fully supported; their
security is ensured as each query modification is validated by the API. White-filtering
and blacklisting are unnecessary as dynamic inputs are specified using binded variables.
In the proposed API, column lengths (e.g. for varchar fields) could be stored in the DB class (as
names and data types are) allowing the solution to perform bounds validation for
input data and therefore increase its protection level and overall accuracy.
Java-based prototypes of similar API designs are in progress and under current research efforts.

Related

Is it bad practice to store SQL stored procedures and parameters in a database table

We have a use case where an app that sends out emails finds a specific string ('smart tag') in an email and replaces it with the results of a stored procedure.
So for example the email could have Dear <ST:Name> in the body, and then the code would identify this string, run the stored procedure to find the client name passing in the client id as a parameter.
The list of these tags and the stored procedures that need to be run are currently hard coded, so every time a new 'smart tag' needs to be added, a code change and deployment is required.
Our BA's our skilled in SQL and want to be able to add new tags manually.
Is it bad practice to store the procedure and parameters in a database table? Would this be a suitable design for such a table? Would it be necessary to store parameter type?
SmartTag
SmartTagId SmartTag StoredProcedure
SmartTagParameters
SmartTagParameterId SmartTagId ParameterName
Table driven configuration, data driven programming, is good.
The primary thing to watch out for is SQL Injection risk (or in your case it would be called 'tag injection'...): one could use the email as an attack vector to gain elevated privileges by inserting a crafted procedure that would be run under higher privileges. Note that this is more than just the usuall caution around SQL Injection, since you are already accepting arbitrary code to be executed. This is more of a sandboxing problem.
Typical problems are from the type system: parameters have various types but the declaration tables have a string type for them. SQL_VARIANT can help.
Another potential problem is the language to declare and discover tags. Soon you'll be asked to recognize <tag:foo>, but only before <tag:bar>. A fully fledged context sensitive parser usually follows shortly after first iteration... It would be helpful if you can help by leveraging something already familiar (eg. think how JQuery uses the CSS selector syntax). HTMLAgilityPack could help you perhaps (and btw, this is a task perfect for SQLCLR, don't try to build elaborate statefull parser in T-SQL...).
It's not bad practice, what you are doing is totally fine. As long as only your admin/BA can add and change parameters and change configuration you do not have to worry about injection. If users can add and change parameters you really need to check there input and whitelist certain chars.
It's not only sql injection you have to check, but cross site scripting and dom injection and cross site request forgery as well. The merged text is displayed on a users computer, so you have to protect him when viewing your merge result.
Interesting question, will follow up as it has something to do with mine. Is not bad practice at all. In fact, we are using same approach. I'm trying to achieve similar goals on my XSL editor. I'm using a combination of XML tags, stored procedures and VB.Net logic to do the replacements.
I'm using a combination of a table with all the used XML tags (they are used on other places on the application) and stored procedures that do all the dirty job. One set of sp transforms from text with tags to a user readable text. Other set of procedures creates an XML tree from the XML tags table so the users can choose from to edit their text.
SQL Injection is not an issue for us as we use these procedures to create emails, not to parse them from external sources.
Regarding a comment on one of the question, we manage the tags also directly from SSMS, no admin window to manage them, at least for now. But we plan to add a simple admin window to manage the tags so it would be easier to add/delete/modify them once the application is deployed.

How to make data access layer for SQL Server and MySql

I'm building a data access layer and need to be able switch between two providers in different environments.
How do I structure this? I'm using a repository pattern and have e.g. a CarRepository class and a Car class. The CarRepository class is responsible for saving, deleting and loading from the database.
I have a Database class, responsible for connecting to the database, and executing the query (sending a SqlCommand for SQL Server). The SQL syntax for the underlying databases is different and the parameter syntax is also different (SQL Server uses # and MySql uses ?).
I would like an approach where I can make the least effort in making my application run on both platforms.
The obvious method is making a MySqlCarRepository and a SqlServerCarRepository, but that introduces a heavy amount of maintenance. Are there any good approaches to this scenario? Maybe keeping a static class with static strings containing the SQL statements for the different SQL flavours? (how about parameter syntax then?)
Any advice is welcome
(Please note that ORM (Nhibernate, Linq2Sql etc) is not an option)
The approach I follow is to first-of-all use the ADO Provider Factories to abstract the data access implementation. So I will use IDbConnection and so forth in the code.
Then I have an abstraction for a query. I can then use Query objects that contain the actual sql statements. These Query objects are created from RawQuery or various query builders (insert/update/delete/etc.) that have implementations for each provider type. The specific raw queries will need to be coded and obtained specific to the DB you need since there is no gettin passed that.
There is quite a bit of leg work involved in coding this 'plumbing' and I have not had a situation where I actually require different platforms so I have not bothered coding some small bits that I know need some ironing out but you are welcome to contact if you are interested in seeing some code.
Can you use any code generation tools?
I used to use Code Smith in another life and had templates that would generate POCO objects from DB tables, repository classes for each object and stored procedures. Worked alright after fine tuning the templates, and there were plenty examples on the net.
But this was way before I saw the light with NHibernate!
A pattern for accessing multiple database types is the DAO (Data Access Object) pattern. This could suit your particular need if you can't/don't use an ORM. The following article explains the pattern for Java but it is still very relevant for C#:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

Sanitize Silverlight input

Hey, I have a silverlight application that allows the user to modify their username, password, bio etc. This information is stored in a MySQL database and retrieved used a WCF webservice.
I need to sanitize all information received from the user before it gets into the database. At the moment I can't store apostrophes in my DB. Where is the best place to sanitize the input (silverlight or WCF methods) and how do I go about it?
BTW, I am not worried about SQL injection as I will be implementing parametrized queries in a few days.
Thanks
The correct answer here is somewhat of a matter of architectural preference. This type of user input validation is a system rule. Many would say that all rule implementation should be done on the service side. From a strict separation of concerns point of view all rules should be enforced in the business logic on the service side of the system.
But, when this kind of validation is handled on the client more immediate feedback can be given to the user resulting in a more usable interface. With the added benefit of not producing any network traffic merely for the purpose of telling the user that he pressed the wrong key.
In the end neither approach is wrong. The 'best' approach can really only be determined by what you want for your system. Architectural purity vs. user responsiveness.
You are right to use parameterized queries. Alternatively, you could use an ORM and also get the SQL injection protection.

Converting project to SQL Server, design thoughts?

Currently, I'm sitting on an ugly business application written in Access that takes a spreadsheet on a bi-daily basis and imports it into a MDB. I am currently converting a major project that includes this into SQL Server and .net, specifically in c#.
To house this information there are two tables (alias names here) that I will call Master_Prod and Master_Sheet joined on an identity key parent to the Master_Prod table, ProdID. There are also two more tables to store history, History_Prod and History_Sheet. There are more tables that extend off of Master_Prod but keeping this limited to two tables for explanation purposes.
Since this was written in Access, the subroutine to handle this file is littered with manually coded triggers to deal with history that were and have been a constant pain to keep up with, one reason why I'm glad this is moving to a database server rather than a RAD tool. I am writing triggers to handle history tracking.
My plan is/was to create an object modeling the spreadsheet, parse the data into it and use LINQ to do some checks client side before sending the data to the server... Basically I need to compare the data in the sheet to a matching record (Unless none exist, then its new). If any of the fields have been altered I want to send the update.
Originally I was hoping to put this procedure into some sort of CLR assembly that accepts an IEnumerable list since I'll have the spreadsheet in this form already but I've recently learned this is going to be paired with a rather important database server that I am very concerned with bogging down.
Is this worth putting a CLR stored procedure in for? There are other points of entry where data enters and if I could build a procedure to handle them given the objects passed in then I could take a lot of business rule away from the application at the expense of potential database performance.
Basically I want to take the update checking away from the client and put it on the database so the data system manages whether or not the table should be updated so the history trigger can fire off.
Thoughts on a better way to implement this along the same direction?
Use SSIS. Use Excel Source to read the spreadsheets, perhaps use a Lookup Transformation to detect new items and finally use a SQL Server Destination to insert the stream of missing items into SQL.
SSIS is way better fit to these kind of jobs that writing something from scratch, no matter how much fun linq is. SSIS Packages are easier to debug, maintain and refactor than some dll with forgoten sources. Besides, you will not be able to match the refinements SSIS has in managing its buffers for high troughput Data Flows.
Originally I was hoping to put this
procedure into some sort of CLR
assembly that accepts an IEnumerable
list since I'll have the spreadsheet
in this form already but I've recently
learned this is going to be paired
with a rather important database
server that I am very concerned with
bogging down.
Does not work. Any input into a C# written CLR procedure STILL has to follow normal SQL semantics. All that can change is the internal setup. Any communication up with the client has to be done in SQL. Which means executions / method calls. No way to directly pass in an enumerable of objects.
My plan is/was to create an object
modeling the spreadsheet, parse the
data into it and use LINQ to do some
checks client side before sending the
data to the server... Basically I need
to compare the data in the sheet to a
matching record (Unless none exist,
then its new). If any of the fields
have been altered I want to send the
update.
You probably need to pick a "centricity" for your approach - i.e. data-centric or object-centric.
I would probably model the data appropriately first. This is because relational databases (or even non-normalized models represented in relational databases) will often outlive client tools/libraries applications. I would probably start trying to model in a normal form and think about the triggers to maintain audit/history as you mention during this time also.
I would typically then think of the data coming in (not an object model or an entity, really). So then I focus on the format and semantics of the inputs and see if there is misfit in my data model - perhaps there were assumptions in my data model which were incorrect. Yes, I'm not thinking of making an object model which validates the spreadsheet even though spreadsheets are notoriously fickle input sources. Like Remus, I would simply use SSIS to bring it in - perhaps to a staging table and then some more validation before applying it to production tables with some T-SQL.
Then I would think about a client tool which had an object model based on my good solid data model.
Alternatively, the object approach would mean modeling the spreadsheet, but also an object model which needs to be persisted to the database - and perhaps you now have two object models (spreadsheet and full business domain) and database model (storage persistence), if the spreadsheet object model is not as complete as the system's business domain object model.
I can think of an example where I had a throwaway external object model kind of like this. It read a "master file" which was a layout file describing an input file. This object model allowed the program to build SSIS packages (and BCP and SQL scripts) to import/export/do other operations on these files. Effectively it was a throwaway object model - it was not used as the actual model for the data in the rows or any kind of navigation between parent and child rows, etc., but simply an internal representation for internal purposes - it didn't necessarily correspond to a "domain" entity.

SQL Injection filter method for ASP.NET

I've got fields that are free-form text and allow just about any combination of numbers/symbols. What's the best way to validate these to prevent SQL Injection? Can I run a simple replace of tick marks? Is there a method out there I can plug in to use?
Just use parameterized queries! Check out this article here: http://www.functionx.com/aspnet/sqlserver/parameterized.htm
There are various methods outlined here:
How To: Protect From SQL Injection in ASP.NET
quote:
Countermeasures include using a list of acceptable characters to constrain input, using parameterized SQL for data access, and using a least privileged account that has restricted permissions in the database. Using stored procedures with parameterized SQL is the recommended approach because SQL parameters are type safe. Type-safe SQL parameters can also be used with dynamic SQL. In situations where parameterized SQL cannot be used, consider using character escaping techniques.
Validation controls can help, though run them server side, not client side. ASP.NET does have some protection built in also, but I wouldn't rely on it alone.

Categories