sql >> Database >  >> RDS >> Mysql

SQL SERVER – Een truc om met dynamische SQL om te gaan om een ​​SQL-injectieaanval te voorkomen?

SQL Server heeft zoveel dingen te leren en ik vind het altijd geweldig. Mijn gesprekken met klanten komen vaak met beveiligingsvragen, vooral rond SQL-injectie. Velen hebben beweerd dat SQL-injectie een SQL Server-probleem is. Het kost me nogal wat tijd om ze te laten weten dat er niets is over SQL Server en SQL Injection. SQL-injectie is het resultaat van verkeerde coderingspraktijken. Een van de aanbevelingen die ik geef gaat over het niet gebruiken van Dynamic SQL. Er kunnen situaties zijn waarin u het niet kunt vermijden. Mijn enige advies zou zijn, vermijd indien mogelijk. In deze blog zou ik een SQL-injectieprobleem demonstreren vanwege dynamische SQL en een mogelijke oplossing die u kunt hebben.

Laten we aannemen dat we een eenvoudige zoekpagina hebben waar de gebruiker de lege zoekfunctie kan gebruiken of een filter kan geven in elk veld. We hebben twee velden voorzien om "Voornaam" en "Achternaam" te gebruiken. De gebruiker typt iets en drukt op zoeken. Hier is onze code van opgeslagen procedure die achter de schermen vuurt.

USE AdventureWorks2014
GO
CREATE PROCEDURE search_first_or_last
@firstName NVARCHAR(50)
,@lastName NVARCHAR(50)
AS
BEGIN
DECLARE @sql NVARCHAR(4000)
SELECT @sql = ' SELECT FirstName ,MiddleName, LastName' +
' FROM Person.Person WHERE 1 = 1 '
IF @firstName IS NOT NULL
SELECT @sql = @sql + ' AND FirstName LIKE ''' + @firstName + ''''
IF @lastName IS NOT NULL
SELECT @sql = @sql + ' AND LastName LIKE ''' + @lastName + ''''
EXEC (@sql)
END

Als ik deze string gebruik om in achternaam uit te voeren ”;drop table t1–

EXEC search_first_or_last '%K%', ''';drop table t1--'

De dynamische tekenreeks zou zijn

SELECT FirstName, MiddleName, LastName FROM Person.
Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'

Zie je het probleem? Ja, gebruikers kunnen tabel t1 laten vallen als de code wordt uitgevoerd onder een account met hoge bevoegdheden.

Een van de oplossingen voor het probleem zou zijn om sp_executesql te gebruiken. Hier is de betere versie met

CREATE PROCEDURE search_first_or_last
@firstName NVARCHAR(50)
,@lastName NVARCHAR(50)
AS
BEGIN
DECLARE @sql NVARCHAR(4000)
SELECT @sql = ' SELECT FirstName , MiddleName, LastName' +
' FROM Person.Person WHERE 1 = 1 '
IF @firstName IS NOT NULL
SELECT @sql = @sql + ' AND FirstName LIKE @firstName'
IF @lastName IS NOT NULL
SELECT @sql = @sql + ' AND LastName LIKE @lastName '
EXEC sp_executesql @sql
,N'@firstName nvarchar(50), @lastName nvarchar(50)'
,@firstName
,@lastName
END

Ik hoop dat je dit kunt gebruiken en implementeren in je project. Gebruikt u deze eenvoudige technieken in uw productiecode? Heb je ooit soortgelijke problemen ondervonden tijdens een audit? Laat me weten wat je ervan hebt geleerd.


  1. Hoe een string te vullen met voor-/achtervolgende karakters in MySQL – LPAD(), RPAD()

  2. Waarde berekenen met behulp van de vorige waarde van een rij in T-SQL

  3. 4 manieren om dubbele rijen te vinden in MySQL

  4. Controleren of een T-SQL UDF schemagebonden is (zelfs als het versleuteld is)