In de nasleep van de aanval op de Colonial Pipeline en andere spraakmakende gevallen, zijn it-teams mogelijk gehaast de versterking van hun endpoint-bescherming aan het controleren. Maar iedereen in de ontwikkelaarscommunity weet dat zwakke punten in security daar niet beginnen en eindigen; schrijf code onjuist of met onvoldoende security, en je codeert ook voor toekomstige web-aanvallen.
Webkwetsbaarheden zijn een probleem dat zelfs de grootste technologiebedrijven treft. Vraag het maar aan Tesla, dat in 2014 een kwetsbaarheid in zijn auto-aanpassingsfunctie had ontdekt, Fortnite, wiens kwetsbaarheid in 2019 werd ontdekt waardoor tachtig miljoen gebruikersgegevens in gevaar waren, of Apple, die vorig jaar naar verluidt securityonderzoekers net onder de drie ton had betaald om fouten in hun digitale omgeving te vinden en onder de aandacht te brengen.
Kwetsbaarheden in webapplicaties hebben betrekking op een groot aantal verschillende codeerproblemen. Maar alle bovenstaande voorbeelden zijn of bevatten een zeer specifiek type probleem.
Verdedigingslinie
Sql (structured query language)-injectie is een van de gevaarlijkste en meest voorkomende kwetsbaarheden. Maar er zijn een aantal best practices die ontwikkelaars kunnen volgen om aanvallen met sql-injectie te voorkomen.
De eerste is om ervoor waken dat invoervalidatie aan de klantzijde niet de enige verdedigingslinie is. Deze validatie is een geweldig hulpmiddel voor een verbeterde gebruikerservaring, maar het werkt niet als een securitymechanisme. Het is eenvoudig om validatie aan de klantzijde te verwijderen door de javascript-code die in de browser is geladen te wijzigen, of door een eenvoudige http-aanroep naar de backend uit te voeren in een client-server-architectuur met een parameter die een sql-injectie veroorzaakt. Ontwikkelaars moeten alles wat een klant verzendt als potentieel schadelijk beschouwen en moeten daarom valideren aan de serverzijde, idealiter zo dicht mogelijk bij de bron.
Ontwikkelaars moeten ook goed nadenken over gebruikersrechten voor databases. Alle sql-injectieaanvallen zijn schadelijk, maar sommige zijn schadelijker dan andere: toegang krijgen tot gebruikersinformatie is één ding, maar deze wijzigen of verwijderen is iets anders.
Om de impact van een sql-injectie te minimaliseren, moeten ontwikkelaars strategisch omgaan met de privileges van een applicatie op een database. Moet een specifieke applicatie echt alle databases kunnen lezen, schrijven en bijwerken? Is het nodig dat het tabellen kan legen of verwijderen?
Naast dat elke applicatie vrij spel heeft over een database, is het ook onverstandig om één databasegebruiker voor een applicatie te hebben. Meerdere databasegebruikers maken en deze koppelen aan specifieke applicatierollen werkt op dezelfde manier als branddeuren om een brand te bedwingen; voorkomen dat een aanval snel een hele database overneemt.
Veel talen
Een cruciale manier waarop ontwikkelaars zichzelf moeten beschermen, is door ‘prepared statements’ en ‘query parametrering’ te gebruiken. Veel talen hebben ingebouwde functies die sql-injecties helpen voorkomen, en dus kan je bij het schrijven van sql-query’s een prepared statement gebruiken om de query samen te stellen.
Prepared statements zijn in te zetten om query parametrering uit te voeren, waardoor de sql-statements die zijn in te voeren, worden beperkt. Een ontwikkelaar maakt een basisquery met tijdelijke aanduidingen en vervolgens kunnen door de gebruiker opgegeven parameters veilig aan deze tijdelijke aanduidingen worden gekoppeld. Bij gebruik van een echt prepared statement en geparametriseerde query’s, zal de database eerst het query-uitvoeringsplan bouwen op basis van de querystring met tijdelijke aanduidingen, en vervolgens de (niet-vertrouwde) parameters naar de database sturen.
Omdat het queryplan al is gemaakt, hebben de parameters hier geen invloed meer op en blokkeert dit de injectie volledig. Prepared statements met query parametrering zijn daarom de beste verdediging tegen sql-injectie.
Parametrering is ook van het grootste belang bij het werken met opgeslagen procedures. Veel mensen denken dat het werken met opgeslagen procedures een goede manier is om sql-injectie te voorkomen, maar dit is niet altijd het geval. Net als alle sql-query’s die binnen een toepassing worden gemaakt, kan een opgeslagen procedure kwaadwillig worden geïnjecteerd. Daarom moeten ontwikkelaars, net als bij sql-query’s, de query’s parametriseren in hun opgeslagen procedure, in plaats van de parameters samenvoegen, om te beschermen tegen injectie.
Er zijn echter situaties waarin prepared statements niet beschikbaar zijn. Als een bepaalde taal geen prepared statements ondersteunt, of als een oudere database ontwikkelaars niet toestaat om de gebruikersinvoer als parameters te leveren, dan is invoervalidatie een acceptabel alternatief. Teams moeten ervoor zorgen dat invoervalidatie afhankelijk is van toelating en niet van blokkering – door een goed onderhouden bibliotheek te gebruiken of door een regel te maken die alle toegestane patronen beschrijft met bijvoorbeeld een reguliere expressie. Zelfs als prepared statements beschikbaar zijn, is invoervalidatie een must.
Meerlaagse security
Naast query parametrering en invoervalidatie, zouden ontwikkelaars moeten overwegen om een object-relationele mapping (orm)-laag te gebruiken als bescherming tegen injectie. Dit transformeert de gegevens uit een database in objecten en vice versa, waardoor expliciete sql-query’s en dus het risico op sql-injectie-aanvallen worden verminderd. Er moet echter worden benadrukt dat er nog steeds kwetsbaarheden kunnen worden gecreëerd binnen orm-bibliotheken als de verkeerde of verouderde versies van sequelize of hibernate worden gebruikt, dus ontwikkelaars moeten waakzaam zijn.
Uiteindelijk, welke securitystrategieën ook worden ingezet, er moet een strikt beoordelingssysteem zijn om code te beoordelen en eventuele kwetsbaarheden te signaleren. Code-review en pair-programmering maken dit mogelijk, maar bij handmatige reviewprocessen zijn er altijd foutenmarges. Voor de hoogste securityniveaus moeten ontwikkelaars speciaal ontworpen scantools gebruiken om automatisch te controleren op kwetsbaarheden voor sql-injectie en hen te waarschuwen voor eventuele zwakheden in hun code.
Sql-injectieaanvallen zijn een gevaarlijke online-bedreiging, maar ze zijn te verdedigen. Met een zero-trust-aanpak, het gebruik van prepared statements en parameters en een streng code-controleproces, kunnen ontwikkelaars alle injectiepogingen blokkeren. Nu cybercriminaliteit samen met digitalisering groeit, is het belangrijker dan ooit dat ontwikkelaars security in de kern van hun code schrijven.