Mysql
 sql >> Baza danych >  >> RDS >> Mysql

SQL SERVER – Jedna sztuczka do obsługi dynamicznego SQL, aby uniknąć ataku SQL Injection?

SQL Server ma tak wiele do nauczenia się i zawsze uważam to za niesamowite. W moich rozmowach z klientami często pojawiają się pytania dotyczące bezpieczeństwa, zwłaszcza dotyczące SQL Injection. Wielu twierdziło, że wstrzyknięcie SQL jest problemem SQL Server. Zajęło mi trochę czasu, zanim dowiedziałem się, że nie ma nic o SQL Server i SQL Injection. SQL Injection jest wynikiem złych praktyk kodowania. Jedno z moich zaleceń dotyczy nieużywania Dynamic SQL. Mogą wystąpić sytuacje, w których nie można tego uniknąć. Moją jedyną radą byłoby unikanie, jeśli to możliwe. W tym blogu zademonstrowałbym problem wstrzykiwania SQL z powodu dynamicznego SQL i możliwego rozwiązania.

Załóżmy, że mamy prostą stronę wyszukiwania, na której użytkownik może użyć pustego wyszukiwania lub wprowadzić filtr w dowolnym polu. Udostępniliśmy dwa pola do użycia „Imię” i „Nazwisko”. Użytkownik coś wpisuje i klika w wyszukiwarkę. Oto nasz kod procedury składowanej, która uruchamia się za kulisami.

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

Jeśli użyję tego ciągu do wykonania na nazwisko ”;upuść tabelę t1–

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

ciąg dynamiczny byłby

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

Czy widzisz problem? Tak, użytkownicy mogą usunąć tabelę t1, jeśli kod działa na koncie o wysokim poziomie uprawnień.

Jednym z rozwiązań problemu byłoby użycie sp_executesql. Oto lepsza wersja za pomocą

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

Mam nadzieję, że będziesz w stanie to wykorzystać i wdrożyć w swoim projekcie. Czy używasz tych prostych technik w swoim kodzie produkcyjnym? Czy kiedykolwiek napotkałeś podobne problemy podczas audytu? Daj mi znać o swoich odkryciach.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. brew zainstaluj mysql na macOS

  2. Jak usunąć wszystkie znaki niealfanumeryczne z ciągu w MySQL?

  3. Jak wstawić wartości w tabeli z kluczem obcym za pomocą MySQL?

  4. Jak zarządzać MySQL — dla administratorów baz danych Oracle

  5. Generowanie drzewa opartego na głębokości z danych hierarchicznych w MySQL (bez CTE)