Of het nu gaat om kleine of grote systemen, ik vind het fijn om veilige software te bouwen. Ik weet, dat ik daarin niet alleen ben. Sterker nog, ik durf wel te stellen dat iedereen veilige software wil maken. Hoewel ik dat al best een tijdje doe (software bouwen in het algemeen bedoel ik dan), vind ik het ook nog steeds lastig in een paar zinnen te beschrijven wat dat dan is… veilige software. Als het al zou lukken, dan is zo’n beschrijving ook weer niet eeuwig houdbaar. Zeker in de IT geldt: wat vandaag als definitie wordt aangenomen, kan morgen weer achterhaald zijn. Wat dat betreft had de oude Griek Heraclitus wel gelijk: ‘verandering is de enige constante’. Voor mij is dat misschien ook waarom software bouwen zo interessant blijft.
Het hangt ervan af
Dus een beschrijving of definitie geven van veilige software is ingewikkeld, maar is het ook lastig om te ‘doen’? Het antwoord is, net als zo vaak in de IT: ‘dat hangt ervan af’. Als je veilige software ziet als iets dat je éénmalig ontwerpt en realiseert, ja dan is het heel lastig. Als je daarentegen veilige software ziet als een bewegend doelwit en je processen zijn zo ingericht dat daar rekening mee gehouden wordt… en je steeds leert en verbetert… dan valt het wel mee. Begin met de basis, het fundament. Benut wat je nu weet van de omgeving, het gebruik en de gestelde eisen. Haal vervolgens tijdens het bouwen van de software steeds zoveel mogelijk informatie op (denk aan risico modellen, privacy eisen, informatiebeleid, etc.). Bouw door op wat je hebt: software beveiligen gebeurt door maatregelen in ‘laagjes’ op elkaar te stapelen.
Het sleutelwoord in de vorige paragraaf is wat mij betreft: ‘steeds’. Dit is dus niet iets wat je één keer moet doen, maar wat je regelmatig terug laat komen. Ik voeg dus graag (en met regelmaat) op basis van nieuwe ideeën en inzichten zaken toe, waarbij ik functionaliteit en beheersbaarheid natuurlijk niet uit het oog verlies. In dit artikel wil ik enkele van die ideeën benoemen, vooral de wat recentere. Sommige zijn in mijn eigen teams ontstaan terwijl andere weer uit de vakliteratuur komen.
“Veiligheid is een onderdeel van elke fase in het leven van een product of dienst. Van ontwerp tot realisatie, elke iteratie weer.“
Vroeger
Vroeger was het leven simpeler, het IT leven dan. Ik denk nog even terug aan de tijd dat software veiligheid nog gelijkstond aan het installeren van firewalls (‘we maken een DMZ!’) en het laten uitvoeren van een penetratietest door een extern bureau. We zagen in die tijd software veiligheid als een zogeheten ‘Gate’. Kwam je daar doorheen, dan was je software veilig. De vergelijking ligt voor de hand, dus ik maak hem maar: de ‘Security Check’ op de luchthaven. Dit was oorspronkelijk alleen een ticket controle op de runway, net voor het instappen. Tegenwoordig is dat het gelaagde model, dat we allemaal wel kennen. Verschillende checks en validaties zorgen ‘in laagjes’ voor de veiligheid van toestellen, luchthaven en passagiers. En we zien nog maar een klein deel, want achter de schermen vindt geautomatiseerd nog een veelvoud van controles plaats.
Dit is misschien wel de grootste verandering die we op dit thema in de jaren hebben moeten maken. Daar waar we vroeger gewend waren software achteraf te toetsen en te beveiligen, is het nu een onderdeel van elke fase in het leven van een product of dienst. Van ontwerp tot realisatie, elke iteratie weer.
De laagjes
Laagjes dus. Voor we hier naar gaan kijken wil ik het nog hebben over het doel van dit alles. Natuurlijk willen we veilige software, maar omdat de echte definitie lastig te geven is neem ik een uitgangspunt.
“We willen bij het bouwen van software het risico dat onherroepelijk ontstaat minimaliseren. Als er dan toch iets misgaat, willen we dat de impact zo klein mogelijk blijft.”
Niets mis mee wat mij betreft, maar dit geeft wel aanleiding om het te hebben over het volgende. Om te kunnen werken aan veilige software heb je mensen nodig die zich doordrongen zijn van deze risico’s. Ik bedoel hier niet per se ‘van de hoed en de rand’, maar wel het besef dat elke wijziging of feature nieuwe kwetsbaarheden kan introduceren. Ik heb het ook niet alleen over ontwikkelaars, want het gaat hier duidelijk om alle betrokkenen. Dus ook een Product Owner of een Business Process Owner. We noemen dit ook wel de security cultuur of veiligheidsklimaat. Er moet in een organisatie voldoende ruimte, aandacht en budget zijn om continu te werken aan veilige software.
Shift Left
Wat mij betreft niet eens echt een laagje, eerder het fundamentele concept waarop de laagjes steunen. De term ‘Shift Left’ komt uit de hoek van het software testen. In het kort betekent het, dat we testen niet meer aan het eind doen (als een soort Quality Gate), maar integraal onderdeel maken van elke fase in de software ontwikkeling. Dit doen we net zo met software security activiteiten en maatregelen: we schuiven ze zogezegd dus naar links:
De ‘software security’ komt niet langer meer pas aan het eind van een proces ter sprake, maar is een onderdeel van elk van de fasen!
Persona’s
In de requirements fase van een feature maak ik graag gebruik van persona’s. Dit zijn gedetailleerde, omschrijvingen van de personen die het product gaan gebruiken. Hoewel ze fictief zijn, creëer je hiermee toch een vorm van echtheid. Het is nu eenmaal makkelijker om ons te verplaatsen in mensen dan in doelgroepen of ‘’target audiences’’. De insteek van deze persona’s is vaak functioneel, maar ze kunnen ook gebruikt worden om (vanuit het functionele vertrekpunt) een beeld te krijgen van de autorisaties die nodig zijn.
Neem bovenstaand persona van een applicatie genaamd ‘Amped’. Als we hier autorisaties uit gaan halen, doen we dat het beste in de vorm van Business Rules:
Bezoekers van de applicatie Amped (‘Shelly the Sharer’) moeten
- content kunnen lezen op Amped;
- content kunnen delen op Amped;
- content van Amped kunnen delen op platformen buiten Amped;
Dit is natuurlijk maar een eenvoudig voorbeeld, maar je ziet al wel dat dit makkelijker te communiceren is dan bijvoorbeeld een ingewikkelde autorisatiematrix in Microsoft Excel!
Evil User Stories
Gewone ‘User Stories’ kennen we wel natuurlijk: de korte beschrijvende verhaaltjes vanuit het oogpunt van de gebruiker om duidelijk te maken (of krijgen) wat deze nodig heeft of wil. Met vaak als doel dit uiteindelijk met een ontwikkelteam te realiseren. Je kunt ditzelfde systeem ook gebruiken om met het team vanuit een kwaadwillende gebruiker te denken en zo een ‘Evil User Story’ op te stellen. Ik merk vaak, dat dit in het begin wat lastig en onwennig is. Echter na een paar sprints komen de ‘goede’ ideeën meestal vanzelf! Bijkomend voordeel: afgeronde Evil User Stories kun je af en toe doorspitten en ze opnieuw in een sprint zetten.
Mob Testing
Je kunt de Evil User Stories behandelen als normale User Stories en ze door teamleden laten oppakken. Er zijn echter ook andere methoden om hier mee aan de slag te gaan, bijvoorbeeld met iets als ‘Mob Testing’. Deze methode gaat als volgt: het hele team werkt aan dezelfde Evil User Story, op dezelfde locatie, samenwerkend achter één computer. Eén teamlid zit achter het toetsenbord (de ‘Driver’), één teamlid geeft de aanwijzingen (dat is de ‘Navigator’) en de rest (de menigte, oftewel de ‘mob’) kijkt mee en stelt vragen of maakt opmerkingen. Dit is een variant op Mob Programming, maar bij testen werkt het ook.
Security by Design, Privacy by Design
Twee onderwerpen samengepakt en niet de kleinste wat mij betreft. Gek gezegd: op elk van deze onderwerpen kun je afstuderen. Net als met de andere onderwerpen in dit artikel gaat het er niet om ze in volledigheid te behandelen. Weten dat ‘iets’ bestaat en hoe je er mee zou kunnen beginnen is een eerste stap.
Security en Privacy by Design gaat over het nemen van maatregelen vanaf het begin, nog voor dat de eerste regel code is geschreven. Het staat daarmee dus recht tegenover de security testen e.d. die we vroeger helemaal aan het eind van de lifecycle deden. Als voorbeeld eerder gaven we de pen-test, die als een soort Quality Gate net voor de productiegang wordt uitgevoerd. Het is daarnaast iets wat continu in de levensloop van een product of dienst van toepassing blijft. Elke sprint, elke review, elke release. Zelfs bij het afdanken van het product speelt dit een rol.
Bij deze twee onderwerpen begint het met ‘awareness’. Zorg dat alle betrokkenen (business-, process- en product owners) op de hoogte zijn en blijven van de noodzaak van veilige software. Gezond verstand is hierbij belangrijk, maar ook bijblijven in de vorm van regelmatige trainingen omdat inzichten steeds veranderen. Enkele maatregelen:
- Vermijd ‘Roll your own’, oftewel maak niet iets zelf wat uit betrouwbare bron al te krijgen is. Als voorbeeld gebruik ik vaak Identity en Access Management software : dit zelf bouwen is in vrijwel alle gevallen minder veilig dan bijvoorbeeld de software van Microsoft of Auth0 gebruiken (om maar twee willekeurige leveranciers te noemen);
- Zorg voor Security en Privacy Enhancement trainingen voor stakeholders. Zo heeft iedere betrokkene een basiskennis als het om deze onderwerpen gaat. Daarnaast organiseer ik vaak trainingen of richtlijnen voor specifieke rollen. Vooral omdat je niet kunt verwachten, dat iedereen van alle details op de hoogte is;
- Ga uit van Security en Privacy by Default. Dit houdt onder andere in, dat je als nieuwe gebruiker van een applicatie standaard de instellingen zo hebt staan, dat je maximale bescherming van (persoons)gegevens geniet.
Security en privacy liggen wat mij betreft in elkaars verlengde: veel van onze maatregelen beschermen zowel de software als haar gegevens. Daarbij worden de kwetsbaarheden waarbij persoonsgegevens openbaar zouden kunnen worden vaak als het meest ernstig ervaren.
Afhankelijkheden
De software die ik en mijn teams maak is al lang niet meer helemaal van ons. Ze bestaan voor een deel uit frameworks, tools, packages, dependencies, plugins…. Deze componenten zijn in de meeste gevallen Open Source projecten van derden en vallen daarmee buiten scope van Code Reviews en dergelijke. Wanneer er dus kwetsbaarheden optreden in dat deel van de software, lopen we het risico hier te laat -of geheel niet- achter te komen.
Een passende oplossing kan zijn om de gebruikte componenten te analyseren en tegen een openbare database van geregistreerde kwetsbaarheden aan te houden. Hiermee kun je op verschillende momenten in de software lifecycle bepalen of er een verhoogd risico is. Ik noem hier als voorbeeld Dependency Track van OWASP. Dit is een tool, die op basis van de ‘Bill of Material’ bepaalt welke componenten gebruikt worden en gebruikt de National Vulnerability Database om deze te scannen.
CI/CD, SDLC
De software development lifecycle (de SDLC) is een belangrijk mechanisme als het om veiligheid gaat. Het is het proces wat bij het maken en uitbreiden van software steeds doorlopen wordt. Daarmee is het ook het proces waarin al onze inspanningen (ook als het gaat om security) terug te vinden zijn. Neem bijvoorbeeld een Continuous Integration & Continuous Deployment pipeline. De plek waar wijzigingen van ontwikkelaars worden samengevoegd en (na de juiste checks) worden uitgerold op een omgeving. In dit CI/CD proces is feedback ongelooflijk belangrijk! Het vertelt of de code qua syntax correct is (‘it builds!’), maar ook dat vitale onderdelen nog steeds werken zoals bedoeld is (de ‘unit tests’ slagen!) èn dat de wijzigingen van individuele ontwikkelaars elkaar niet in de weg zitten.
Ik stelde al eerder, dat er bij het ontwikkelen van software altijd risico’s ontstaan. Niet al deze risico’s zijn vooraf in te schatten en we moeten desondanks snel kunnen reageren met maatregelen. De SDLC moet dus ook ‘voorzien in het onvoorziene’. Ik denk daarom vooral aan automatische validaties, maar ook aan het ‘in place’ hebben van draaiboek voor het geval er iets misgaat ondanks alle maatregelen.
- Dependency Management: vergelijk gebruikte afhankelijkheden (dependencies) met een openbare database met kwetsbaarheden;
- Static Application Security Testing: feedback op basis van statische code analyse, bijvoorbeeld met een tools als SonarQube of SonarCloud;
- Dynamic Application Security Testing: feedback op basis van gesimuleerde aanvallen op software. Kijk maar eens naar een tool als OWASP ZAP;
- Continuous Testing en Continuous Feedback: testen, valideren en ophalen van feedback in elke fase van het ontwikkel- en voortbrengingsproces;
- Emergency Patch Management: zorg voor een doordacht en beproefd proces als het gaat om het snel uit kunnen brengen van reparaties aan de software.
En hoe nu verder?
Dit zijn op zichzelf kleine toevoegingen. Het echte (lees: meeste) werk zit hem vaak in het introduceren en onderhouden van de eerder genoemde security cultuur of veiligheidsklimaat. Dit gaat niet in één dag en is na de implementatie ook niet klaar. Je moet hier continu met alle betrokkenen aan werken. Ook bestaat 100% veilige software niet en er zullen altijd afwegingen moeten worden gemaakt waar (en tegen welke kosten) de grootste security winst te halen is.
Meer weten over hoe je een ontwikkelorganisatie zover krijgt? Of hoe je de juiste balans vindt tussen risico en zekerheid? Neem contact op.