Onlangs publiceerden het SANS instituut en MITRE een Top 25 van de meest gevaarlijke programmeerfouten. Een belangrijke lijst, vindt Ron Tolido maar volgens hem gaan de makers ervan voorbij aan misschien wel de meest gemaakte fout: er wordt eenvoudigweg teveel geprogrammeerd.
Het is een veilig gevoel dat we in het vakgebied sinds kort over een Top 25 van Meest Gevaarlijke Programmeerfouten kunnen beschikken. De beste beveiligingsexperts van over de hele wereld hebben hun tanden gezet in de uitdaging en het resultaat mag er zijn. De uiteindelijke lijst bevat veel leerzaam materiaal – overigens ook voor hackers die zoeken naar bijscholing – en elke serieuze systeemontwikkelaar zou deze Top 25 eigenlijk spontaan moeten kunnen opdreunen.
Toch ontbreekt notoir de allergrootste oorzaak van kritieke fouten in software: er wordt nog steeds veel teveel software geschreven. Daaruit blijkt dat de IT onverminderd een pijnlijk jong vakgebied is. De beroepsbeoefenaars blijven hardnekkig zelf problemen veroorzaken om ze daarna met veel aplomb – mogelijk vergezeld van lijstjes, artikelen en zelfs complet boeken – op te lossen. Alle kranen in huis worden wagenwijd opengezet, zodat daarna met trots de allernieuwste, vochtabsorberende dweil tevoorschijn kan worden gehaald. Naarmate meer code met de hand wordt geproduceerd, neemt ook de kans op fouten toe. En hoewel programmeurs misschien een nostalgisch sentiment voelen bij het regel voor regel schrijven van hun software, worden zowel efficiëntie als veiligheid er niet door gediend.
De mogelijk allerbeste manier om minder gevaarlijke fouten te maken tijdens het coderen, is daarom minder coderen. Hier zijn 7 voor de hand liggende manieren om dat te bereiken:
1. Hergebruiken. Steeds meer basisfunctionaliteit wordt gedekt in frameworks of andere herbruikbare componenten, services en bibliotheken. Dit materiaal kan zowel binnen de eigen organisatie zijn ontwikkeld of komt van een andere leverancier. Omdat het om voor hergebruik geschikt bevonden code gaat, mag worden aangenomen dat deze software zeer grondig is getest en beproefd, in ieder geval meer dan gemiddeld. De code hoeft alleen maar gebruikt of aangeroepen te worden, waardoor de interne werking niet hoeft te worden doorgrond. Dit vermindert de complexiteit en daarmee de foutgevoeligheid. Intensief hergebruik levert veel voordelen op, en niet alleen op het gebied van het vermijden van programmeerfouten. Toch zijn er veel ontwikkelaars die denken dat zelfs de meest elementaire functies toch maar beter door henzelf kunnen worden ontwikkeld. Dat is schadelijke zelfoverschatting die steeds duurder betaald wordt. Intensief hergebruik leidt overigens tot een verschuiving van de testactiviteiten: de correcte werking en de betrouwbaarheid van de externe software krijgt de hoogste prioriteit.
2. Genereren. Er komen steeds betere hulpmiddelen om code te genereren uit ontwerpmodellen, of zelfs uit specificaties in een al dan niet natuurlijke taal. De meest populaire en gestandaardiseerde aanpak is Model Driven Architecture (MDA) maar ook Microsoft timmert aan de weg met Domain Specific Languages (DSL’s). Pioniers als de voormalige softwaregoeroe en ruimtetoerist Charles Simonyi werken zelfs aan concepten waarin specificaties in natuurlijke ‘business-taal’ (bijvoorbeeld een taal speciaal bedoeld voor het beschrijven van pensioenregelingen) gelijke tred houden met een vastlegging in programmacode. Specificaties van een hoger abstractieniveau zijn makkelijker te begrijpen en bieden een grote expressiekracht. Daaruit kan veel foutloze en efficiënte code worden geproduceerd met behulp van een – uiteraard uitputtend getest en geoptimaliseerde codegenerator. Grootste valkuil: zelf die generator willen ontwikkelen en onderhouden, een nadrukkelijk te mijden hobbygebiedje voor verveelde programmeurs, op zoek naar nieuwe uitdagingen.
3. Standaardpakketten. Steeds meer organisaties merken dat hun bestaande, zelfgebouwde systemen tot een ondoordringbaar moeras zijn geworden. Het onderhoud ervan kost evenredig veel tijd en de kans op fout neemt alleen maar toe naarmate de oorspronkelijke ontwikkelaars gaandeweg verdwijnen, de documentatie minder enthousiast wordt bijgehouden en de programmatuur obese trekjes begint te vertonen. Opnieuw bouwen op een modern platform is een optie maar het gaat vaak om grote systemen, omvangrijke projecten en daarmee een sterk toegenomen kans op fouten. Standaardpakketten en ERP worden in dit licht nu snel tot een niet te negeren constante, zelfs in bastions waar van oudsher veel huisvlijt voorkomt, zoals de overheid en financiële instellingen. Laat ze zich in Waldorf maar druk maken over het vermijden van bugs, dat is zo ongeveer de redenering. Natuurlijk moet standaard software verder minstens zo uitgebreid worden getest als de eigengemaakte brouwsels. En er loert een addertje onder het gras: het uitgebreid ‘customizen’ van een pakket is hetzelfde als nieuw bouwen, maar dan omslachtiger en met grotere risico’s.
4. Eigen middleware de deur uit. Het leek toentertijd zo’n goed idee: je eigen middleware ontwikkelen om in één klap met steeds terugkerend, infrastructurele softwarefuncties af te rekenen. Maar de jaren zijn verstreken en de industrie heeft ondertussen software ontwikkeld die hetzelfde ‘loodgieterwerk’ doet, maar dan op basis van open standaarde en hoogstwaarschijnlijk een stuk effectiever en robuuster uitgevoerd. Daar zit je dan - met de Wet van de Remmende Voorsprong ter hoogte van je maagstreek - opgescheept met complexe en uiterst gevoelige code die allang geen onderscheidende waarde meer levert. Het is een pijnlijk traject, maar de migratie naar industriële software, al dan niet uit de Open Source wereld – levert in dit geval een opgelucht en veilig gevoel op. Er moeten dus alarmbellen rinkelen op de ontwikkelafdeling die er nog een eigen Enterprise Service Bus, transactiemonitor, database, portal, GUI Handler of Object-to-Relational Mapper op nahoudt.
5. Proceslogica en bedrijfsregels isoleren. Met de komst van een nieuwe generatie Business Process Management (BPM) en Business Rule Engine (BRE) systemen moet elke ontwikkelaar zich serieus afvragen waarom er nog allerlei proceslogica en bedrijfsregels ‘hardcoded’worden ingebakken in de software. Ze samen met de gebruikers in een apart systeem vastleggen - in een taal die door de bedrijfsvoering wordt begrepen – scheelt niet alleen een hoop coderen maar slaat ook nog eens een brug tussen technologie en bedrijfsvoering: het gebied waar van oudsher de meeste misverstanden ontstaan. Overigens kan op dezelfde manier met Business Intelligence worden omgegaan: rapportages, scorecards en dashboards klik je met gespecialiseerde hulpmiddelen aan elkaar; daar komt geen programmeren meer bij kijken. Natuurlijk kun je in bedrijfsregels of in procesbeschrijvingen ook fouten maken, maar de gevoeligheid voor echte ‘bugs’ en inbraken van buitenaf neemt overduidelijk af.
6. Complexe constructies vermijden. Zinloze complexiteit in de IT, vroeg of laat gaan we er de eerste Stille Tocht omheen meemaken. Ontwikkelaars zwermen als vliegen rond complexe constructies als dynamisch polymorfisme, multiple inheritance en xml-to -object-to-relational mapping (en terug). Niet omdat ze die constructies nodig hebben, maar omdat ze worden aangetrokken door lekker foute, analytische uitdagingen. Waarom immers zou je informatie gewoon gestructureerd in een simpele relationele database opslaan – eventueel vergezeld van compacte, doelgerichte triggers en benaderd met SQL – als je er ook een hele objectgeoriënteerde muur omheen kan optrekken? Inclusief alle benodigde transformaties en conversies die daaromheen moeten worden gebouwd, geeft dat een stuk meer beroepsmatige voldoening. En veel programmeertalen evolueren van de weeromstuit mee Java is met al zijn uitbreidingen een kind met een waterhoofd geworden en zelfs het kinderlijk eenvoudige Basic is topzwaar geworden door alle overbodige verbeteringen. Versimpeling is een van de grootste uitdagingen voor de programmeur: met minder constructies om rekening mee te houden, blijft het hoofd koel en leeg, wordt uiteindelijk minder gecodeerd en worden ondoorgrondelijke fouten vermeden.
7. Simpelere programmeertalen. Als de eerstgenoemde 6 verschijnselen serieus zijn genomen, zou het vroeg of laat kunnen gaan opvallen dat er helemaal niet meer zoveel valt te programmeren. Misschien willen we vooral kunnen orkestreren en lijmen en is het goed mogelijk dat onze gebruikers zelf hun applicaties – in ‘mashup’ stijl - bij elkaar klikken. Wie weet passen we samen met die gebruikers de in semi-natuurlijke taal opgestelde bedrijfsregels wel ter plekke aan. Een mooi moment om eens na te gaan of we werkelijk moeilijke, foutgevoelige programmeertalen als Java of C# nog nodig hebben. Met vereenvoudigde, doch krachtige gereedschappen – zonder verleidelijke zijweggetjes en onnodige dikdoenerij – wordt met een minimum aan code het maximale resultaat bereikt.
Als je geen code schrijft, kun je ook geen fouten produceren. Een waarheid als een koe. De Top 25 van meest gevaarlijke programmeerfouten blijft altijd relevant maar de afhankelijkheid ervan kan sterk worden verminderd door uit de buurt van duistere gebieden te blijven. Niets minder dan een cultuuromslag voor een vakgebied dat van oudsher juist de problemen opzoekt.
Zie voor meer informatie het artikel in Automatisering Gids nummer 3, 16 januari 2009.