Share via


Veilige dynamische SQL schrijven in SQL Server

ADO.NET downloaden

SQL-injectie is het proces waarmee een kwaadwillende gebruiker Transact-SQL instructies invoert in plaats van geldige invoer. Als de invoer rechtstreeks aan de server wordt doorgegeven zonder te worden gevalideerd en als de toepassing per ongeluk de geïnjecteerde code uitvoert, kan de aanval gegevens beschadigen of vernietigen.

Elke procedure waarmee SQL-instructies worden gemaakt, moet worden gecontroleerd op beveiligingsproblemen met injectie, omdat SQL Server alle syntactisch geldige query's uitvoert die worden ontvangen. Zelfs geparameteriseerde gegevens kunnen worden gemanipuleerd door een ervaren en vastberaden aanvaller. Als u dynamische SQL gebruikt, moet u uw opdrachten parameteriseren en nooit rechtstreeks parameterwaarden opnemen in de queryreeks.

Anatomie van een SQL-injectieaanval

Het injectieproces werkt door een tekenreeks voortijdig te beëindigen en een nieuwe opdracht toe te voegen. Omdat aan de ingevoegde opdracht mogelijk extra tekenreeksen zijn toegevoegd voordat deze wordt uitgevoerd, beëindigt de malefactor de geïnjecteerde tekenreeks met een opmerkingmarkering '--'. Volgende tekst wordt tijdens de uitvoering genegeerd. Meerdere opdrachten kunnen worden ingevoegd met behulp van een puntkomma (;) scheidingsteken.

Zolang de geïnjecteerde SQL-code syntactisch correct is, kan manipulatie niet programmatisch worden gedetecteerd. Daarom moet u alle gebruikersinvoer valideren en zorgvuldig de code controleren waarmee samengestelde SQL-opdrachten worden uitgevoerd op de server die u gebruikt. Voeg nooit gebruikersinvoer samen die niet is gevalideerd. Tekenreekssamenvoeging is het primaire toegangspunt voor scriptinjectie.

Hier volgen enkele nuttige richtlijnen:

  • Bouw nooit Transact-SQL instructies rechtstreeks vanuit gebruikersinvoer; gebruik opgeslagen procedures om gebruikersinvoer te valideren.

  • Valideer gebruikersinvoer door het testtype, de lengte, de notatie en het bereik te testen. Gebruik de functie Transact-SQL QUOTENAME() om systeemnamen of de functie REPLACE() te escapen om een teken in een tekenreeks te escapen.

  • Implementeer meerdere validatielagen in elke laag van uw toepassing.

  • Test de grootte en het gegevenstype van invoer en dwing de juiste limieten af. Dit kan helpen bij het voorkomen van opzettelijke bufferoverschrijdingen.

  • Test de inhoud van tekenreeksvariabelen en accepteer alleen verwachte waarden. Negeer vermeldingen die binaire gegevens, escapereeksen en opmerkingstekens bevatten.

  • Wanneer u met XML-documenten werkt, valideert u alle gegevens op basis van het bijbehorende schema terwijl deze worden ingevoerd.

  • In omgevingen met meerdere lagen moeten alle gegevens worden gevalideerd voordat ze toegang hebben tot de vertrouwde zone.

  • Accepteer niet de volgende tekenreeksen in velden waaruit bestandsnamen kunnen worden samengesteld: AUX, CLOCK$, COM1 tot en met COM8, CON, CONFIG$, LPT1 tot en met LPT8, NUL en PRN.

  • Gebruik SqlParameter objecten met opgeslagen procedures en opdrachten om typecontrole en lengtevalidatie te bieden.

  • Gebruik Regex expressies in clientcode om ongeldige tekens te filteren.

Dynamische SQL-strategieën

Als u dynamisch gemaakte SQL-instructies uitvoert in uw procedurele code, wordt de eigendomsketen verbroken, waardoor SQL Server de machtigingen van de aanroeper controleert op de objecten die worden geopend door de dynamische SQL.

SQL Server heeft methoden voor het verlenen van toegang tot gegevens met behulp van opgeslagen procedures en door de gebruiker gedefinieerde functies die dynamische SQL uitvoeren.

  • Imitatie gebruiken met de Transact-SQL EXECUTE AS-component.

  • Opgeslagen procedures ondertekenen met certificaten.

UITVOEREN ALS

De EXECUTE AS-component vervangt de machtigingen van de aanroeper door die van de gebruiker die is opgegeven in de EXECUTE AS-component. Geneste opgeslagen procedures of triggers worden onder de beveiligingscontext van de proxygebruiker uitgevoerd. Dit kan toepassingen verbreken die afhankelijk zijn van beveiliging op rijniveau of controle vereisen. Sommige functies die de identiteit van de gebruiker retourneren, retourneren de gebruiker die is opgegeven in de EXECUTE AS-component, niet de oorspronkelijke aanroeper. De uitvoeringscontext wordt pas na uitvoering van de procedure teruggezet naar de oorspronkelijke aanroeper of wanneer er een REVERT-instructie wordt uitgegeven.

Certificaatondertekening

Wanneer een opgeslagen procedure die is ondertekend met een certificaat wordt uitgevoerd, worden de machtigingen die zijn verleend aan de certificaatgebruiker samengevoegd met die van de aanroeper. De uitvoeringscontext blijft hetzelfde; de certificaatgebruiker imiteert de beller niet. Voor het ondertekenen van opgeslagen procedures zijn verschillende stappen vereist om te implementeren. Telkens wanneer de procedure wordt gewijzigd, moet deze opnieuw worden ondertekend.

Toegang tussen databases

Eigendomsketen tussen databases werkt niet in gevallen waarin dynamisch gemaakte SQL-instructies worden uitgevoerd. U kunt dit omzeilen in SQL Server door een opgeslagen procedure te maken die toegang heeft tot gegevens in een andere database en de procedure te ondertekenen met een certificaat dat in beide databases bestaat. Dit geeft gebruikers toegang tot de databasebronnen die door de procedure worden gebruikt zonder hen databasetoegang of -machtigingen te verlenen.

Externe middelen

Zie de volgende informatie bronnen voor meer informatie:

Hulpbron Description
Opgeslagen procedures en SQL-injectie in SQL Server Books Online Onderwerpen beschrijven hoe u opgeslagen procedures maakt en hoe SQL-injectie werkt.

Volgende stappen