Newsgroup: it.comp.software.database
Titolo: SQL injection

Salve a tutti,
vorrei togliermi un dubbio...
Per proteggermi dalla sql injection ho sempre verificato con molta
attenzione i parametri passati alle pagine .asp/.aspx dai form web che
permettevano l'inserimento di informazioni.
Da un po' di tempo sto sviluppando su SQL Server 2000 utilizzando in modo
massiccio le stored procedure.
Posso ritenermi sufficientemente al sicuro dall sql injection utilizzando
le stored procedure ?
Grazie a tutti.
Daniele Imberti
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 le stored procedure ?
Ciao Daniele,
dipende...
se costruisci comandi SQL dinamicamente nelle le stored
procedure sei lo stesso a rischio
dipende anche da come esegui le chiamate, ad esempio
in ADO se utilizzi l'oggetto Command ed imposti
la proprieta' CommandType and adStoredProc oppure
se la imposti a adCmdText, nel secondo caso sei
comunque a rischio
in fondo al post c'e' un esempio di come realizzare
l'injection direttamente in Transact-SQL usando
stored procedures
ecco inoltre alcuni link:
http://www.sqlsecurity.com/faq-inj.asp
http://www.algonet.se/~sommar/dynamic_sql.html
Ciao,
-- 
Gianluca Hotz
Backoffice MVP (SQL Server) MCP SQL Server and MCP Windows
Vice-President of the Italian User Group for SQL Server
Founding Member of the Italian User Group for .NET
http://www.ghotz.com
http://www.ugiss.org
--
-- Demo SQL Injection
USE tempdb
GO
IF OBJECT_ID('dbo.Utenti') IS NOT NULL
 DROP TABLE dbo.Utenti
GO
CREATE TABLE dbo.Utenti(
 IDUtente int IDENTITY(1, 1) NOT NULL,
 NomeUtente varchar(100)  NOT NULL,
 PassUtente varchar(100)  NOT NULL,
 CONSTRAINT pk_Utenti
 PRIMARY KEY (IDUtente)
)
GO
INSERT dbo.Utenti (NomeUtente, PassUtente)
VALUES ('Pippo', 'passwordpippo')
INSERT dbo.Utenti (NomeUtente, PassUtente)
VALUES ('Pluto', 'passwordpluto')
INSERT dbo.Utenti (NomeUtente, PassUtente)
VALUES ('Paperino', 'passwordpaperino')
INSERT dbo.Utenti (NomeUtente, PassUtente)
VALUES ('Paperoga', 'passwordpaperoga')
GO
IF OBJECT_ID('dbo.spsGetUtente') IS NOT NULL
 DROP PROCEDURE dbo.spsGetUtente
GO
CREATE PROCEDURE dbo.spsGetUtente
 @IDUtente int    = NULL,
 @NomeUtente varchar(100) = NULL,
 @PassUtente varchar(100) = NULL
AS
DECLARE @sqlstmt varchar(8000)
SET @sqlstmt = 'SELECT * FROM dbo.Utenti WHERE '
IF @IDUtente IS NOT NULL
 SET @sqlstmt = @sqlstmt + ' IDUtente = ' + CAST(@IDUtente as varchar)
ELSE
 SET @sqlstmt = @sqlstmt
  + ' NomeUtente = ''' + @NomeUtente + ''''
  + ' AND PassUtente = ''' + @PassUtente + ''''
PRINT 'Questo e'' il comando che viene eseguito:'
PRINT @sqlstmt
PRINT ''
EXEC (@sqlstmt)
GO
-- tutto bene
EXEC dbo.spsGetUtente 1
-- tutto bene
EXEC dbo.spsGetUtente NULL, 'pippo', 'passwordpippo'
-- ma cosa succede se passo ad esempio "' OR 1 = 1 --" come utente
-- ed una qualunque stringa come password ?
EXEC dbo.spsGetUtente NULL, ''' OR 1 = 1 --', 'blablabla'
-- viene ritornata l'intera tabella...
-- funziona anche altre stringhe...
-- peggio ancora se la sicurezza per l'utente non e' impostata
-- correttamente, ad esempio se si tratta di un web-server che
-- esegue le richieste come sysadmin...
EXEC dbo.spsGetUtente NULL, ''' OR 1 = 1 EXEC master.dbo.xp_cmdshell 
''dir c:\''--', 'blablabla'
-- ma basta anche solo un utente che sia db_owner nel database...
EXEC dbo.spsGetUtente NULL, ''' OR 1 = 1 DROP TABLE dbo.Utenti --', 
'blablabla'
-- .. la tabella non esiste piu'....
SELECT * FROM dbo.Utenti