SideBar    Logical Puzzle
DOWNLOAD THE CODE:
Download the Code 94268.zip

At callout D, the procedure constructs the PIVOT query and invokes it using dynamic SQL. Note two important points here. First, the derived table PivotInput contains only the columns that need to be involved in the pivot operation: grouping columns (@on_rows), the rotation column (@on_cols), and the aggregation column (@agg_col). This technique lets you prevent implicit grouping by columns that you don’t want to take part in the grouping activity. Second, the list of rotation elements stored in @cols that the procedure constructed dynamically is part of the concatenation (in the parentheses following the IN clause), letting you rotate a dynamic number of elements that are unknown ahead of time. In the query string you’re constructing, the IN list appears to be a list of known elements.

Mitigating SQL Injection Risks
As I’ve noted, sp_pivot’s implementation doesn’t guard against SQL injection attacks. Coverage of SQL injection is outside the scope of this article, but you can learn about SQL injection and how to prevent it by reading “SQL Injection: The Hacker’s Gold Mine” (May 2006, InstantDoc ID 49639) and “Preventing SQL Injection Attack” (August 2004, InstantDoc ID 43012). The following example shows how easy it is to inject code by using the sp_pivot stored procedure:

EXEC Northwind.dbo.sp_pivot
  @query  = N’dbo.Orders’,
  @on_rows  = N’1 AS c) AS D;
PRINT ‘’SQL Injection!
This could have been much
 worse than a PRINT 
command!’’;
SELECT * FROM (select
EmployeeID’,
@on_cols  = N’ShipVia’,
@agg_func = N’COUNT’,
@agg_col  = N’*’;

This invocation of sp_pivot injects a PRINT statement, but you could inject much more destructive code, such as DROP commands and xp_cmdshell.

You can mitigate the risks of SQL injection, but bear in mind that hackers continue to find creative ways to inject code into your systems. If you use dynamic SQL, your operating premise should be that hackers will be able to inject their own code through it. The only way to prevent injection is to not use dynamic SQL. With that in mind, here are a few ways you can mitigate the risks of SQL injection in sp_pivot:

Limit the size of your input parameters. Sp_ pivot defines all parameters as NVARCHAR (MAX), giving hackers a lot of leeway for injecting code. You can define all pivoting elements (grouping column, rotation column, aggregation column) as sysname, for example, to limit the input string size and the opportunities for injecting code. Also, query the metadata to verify that specified columns exist in the input table.

Do not accept a query as input. Instead, accept only a table or view name as input, and check to be sure that the object exists. If you need to perform manipulation to prepare pivoting elements that have expressions, you can always create a view by using such manipulation and then provide the view as input.

Limit the aggregate function name size. For example, define the size as NVARCHAR(12), and check that the function appears in a list of your supported functions.

Use the QUOTENAME function to quote object and column names with square brackets. For example, QUOTENAME (N'col1') becomes [col1], while QUOTENAME (N'col1] DROP TABLE T1 --') becomes [col1]] DROP TABLE T1 --]. The closing square bracket, which is often used as an attempt to inject code, is doubled by the QUOTENAME function, neutralizing injection attempts.

Check the contents of the @cols variable, which contains the concatenated list of rotation elements. Remember that SQL injection can be achieved by injecting code into your data. Look for known strings used in SQL injection, such as --, sp_, xp_, DROP, and so on.

Create the procedure in a specific database and by using the usp_ prefix. To conform to Microsoft’s recommendations and to prevent use of the stored procedure globally in the instance, create sp_ pivot only in the database where you want to allow usage and by using the usp_ prefix instead of sp_.

To implement these security measures, run the code in Web Listing 1 (which you can download at InstantDoc ID 94268) to create the usp_pivot stored procedure in the Northwind database. The code in Listing 2 invokes the procedure to return the sum of freight for each employee and shipper; Table 1 shows the results.

As always, tightening security comes at the cost of decreased flexibility. And although these measures help you mitigate the risk of SQL injection attack, when you use dynamic SQL, it’s hard—if not impossible—to guarantee that you can block all SQL injection attempts. Use dynamic SQL with caution. Still, with these safety measures in place, usp_pivot provides a powerful tool for pivoting data and giving users information as they need to see it.

End of Article

Prev. page     1 2 [3]     next page -->



You must log on before posting a comment.

If you don't have a username & password, please register now.

Reader Comments

The sample code and analysis are extremely helpful. This will save me hours of hard work!

AnilDesai

Article Rating 5 out of 5

AnilDesai, thanks for writing! Glad you found Itzik's article helpful. --Anne Grubb, Web Lead Editor, SQL Server Magazine and Windows IT Pro

AnneG_editor

Article Rating 4 out of 5

Extremely helpful. Question: is the PIVOT function to be supported beyond 2005? Future visions to keep it? When introduced there was no information if they were going to keep this.

dianagele

Article Rating 5 out of 5

Hi dianagele!

Thanks so much for your feedback. I passed your question on to Itzik Ben-Gan, whose response is below.

“Yes it is. It would be unreasonable for Microsoft to add a feature if they’re not planning to support it in future versions. And before dropping support for a feature, they announce deprecation way ahead in the list of deprecated features in Books Online.”

Please let me know if you have any more questions.

Thanks!

Megan Keller

Associate Editor, SQL Server Magazine

mkeller@sqlmag.com

meganbearly

Article Rating 5 out of 5

 
 

ADS BY GOOGLE