Kreeg vandaag de volgende vraag binnen waarvan mijn antwoord ook voor anderen nuttig kan zijn:
Is er een beveiligingsoplossing tegen hard coded databasewachtwoorden, zoals bijvoorbeeld het geval is bij websites die in de programmeercode het MySQL-wachtwoord in een configuratiebestand hebben opgeslagen? Wanneer dit wachtwoord in verkeerde handen valt, dan heeft een kwaadwillend persoon direct de kroonjuwelen van de database in handen. Kan asymmetrische encryptie of kunnen certificaten eventueel uitkomst bieden?
Dit is een goeie vraag. Helaas is er niet echt een oplossing. Het wachtwoord is namelijk de toegangspoort tot MySQL en dus niet uit te bannen. MySQL is hierin niet uniek als platform. Wachtwoorden zijn als authenticatiemiddel een noodzakelijk kwaad om toegang tot allerlei services te krijgen. Algemeen gesproken is er geen heiligmakende oplossing tegen hard coded wachtwoorden. Wel zijn mitigerende maatregelen te nemen.
Uitgangspunt is dat gebruiker ‘root’ overal toegang tot heeft en dus kan het wachtwoord aan deze gebruiker toevertrouwd worden. Daarnaast is strikte monitoring op misbruik aanvullend als voor een bepaald probleem geen afdekkende beveiliging gerealiseerd kan worden.
In de basis komt het neer op het kiezen van één van de volgende twee opties:
- Het wachtwoord niet in een configuratiebestand opslaan.
- Bij het opstarten van MySQL iedere keer het wachtwoord handmatig intoetsen, zodat een sessie opgezet wordt met de service. Vrij omslachtig en niet flexibel.
- Het wachtwoord wel in een configuratiebestand opslaan.
- Minimaliseer toegang tot het bestand door de bestandspermissies zo strikt mogelijk in te stellen. De meest strikte vorm is dat alleen root toegang heeft tot het bestand, bijvoorbeeld zoals het geval is in Linux bij /etc/shadow. Echter is het niet verstandig om een applicatie als root uit te voeren en dus kan logischerwijs een applicatie dat niet als root wordt uitgevoerd een bestand waar alleen root toegang tot heeft niet uitlezen.
- Sla het configuratiebestand altijd buiten de webroot op.
- Zorg ervoor dat na het gebruik van het wachtwoord in software, alle variabelen expliciet verwijderd worden in het geheugen waarin het wachtwoord is opgeslagen.
- Obfusceer het wachtwoord in het configuratiebestand tegen bescherming tegen meekijken (shoulder surfing) door bijvoorbeeld het wachtwoord via base64 te encoderen.
- Sla het wachtwoord niet in een versiebeheersysteem op; zorg voor een separaat bestand waarin alleen het wachtwoord staat.
- Richt stikte monitoring in op het bestand. Als het bestand aangeraakt/gelezen wordt door een ander programma dan bedoeld, dan moeten alarmbellen afgaan.
- Richt strike monitoring in op MySQL. Als iemand anders opeens verbinding maakt met MySQL, dan moeten ook alarmbellen afgaan.
- De software in zijn geheel obfusceren zodat reverse engineering behoorlijk lastig en dus tijdrovend wordt. Dit werkt drempel verhogend.
- Daarnaast minimaliseert het volgende het aanvalsoppervlak van het bestand drastisch. Als het configuratiebestand door een gebruiker anders dan root gelezen moet worden, dan kan de levensduur van het bestand drastisch worden ingekort door bij het opstarten van de server via root het configuratiebestand aan te maken, nog voor het opstarten van de applicatie die verbinding moet maken met MySQL. Als de applicatie is opgestart, dan wordt het bestand vervolgens weer verwijderd door root (via shredding, als geen solid state harde schijf gebruikt wordt).
Daarnaast zal de MySQL-gebruiker zo min mogelijk rechten dan nodig moeten hebben op de database. Voor MySQL geldt dat de gebruiker in menig applicatie geen DROP of TRUNCATE rechten nodig heeft bijvoorbeeld.
Als abstractielaag op de MySQL-gebruiker aanvullend een webservice bouwen die nog fijnmaziger autorisatiecontroles uitvoert dan de basale CRUD-operaties die MySQL kent. Deze constructie biedt veiligheid wanneer data van meerdere klanten in dezelfde database en tabellen opgeslagen wordt. Deze webservice retourneert bijvoorbeeld in een aanvraag alleen data van een bepaalde klant en nooit van meerdere klanten tegelijkertijd. Deze webservice kan tevens op een separate beveiligde server gezet worden, waarbij de MySQL-server die dan ook weer op een andere server staat, via een tweezijdige SSL-verbinding alleen toegang toestaat met de server waar de webservice op draait.
Asymmetrische encryptie biedt volgens mij geen solaas, aangezien je dan ook het dilemma hebt om de private key afgeschermd te houden, vergelijkbaar met het wachtwoorddilemma. Waar ik wel aan zit te denken (ruw idee), maar nog niet tot een oplossing kom, is het gebruik van multi-factor authenticatie. Dat root bijvoorbeeld controleert wie toegang tot MySQL vraagt, door ook te kijken naar het proces ID van de aanvrager en naar bijvoorbeeld omgevingsvariabelen. Of dat root op de server een verbinding opzet naar een andere server (de tweede factor) die zijn fiat geeft om het wachtwoord vrij te geven. Vage ideeën, goed om verder over te brainstormen. Misschien levert het wat innovatiefs op 😉
Behalve het bovenstaande zijn natuurlijk ook zaken als de sterkte van het wachtwoord, het periodiek vervangen van het wachtwoord en het veilig opslaan van het wachtwoord in een wachtwoorddatabase ook enkele aspecten die zeker aandacht behoeven.