Het artikel bespreekt een methodiek waarbij het AI-model Claude wordt gebruikt voor de geautomatiseerde analyse en reductie van het aanvalsoppervlak van software. In plaats van enkel individuele kwetsbaarheden te patchen, richt deze aanpak zich op het beperken van de bereikbaarheid van code, waardoor onbekende kwetsbaarheden moeilijker exploiteerbaar worden.
De belangrijkste methoden zijn:
- Standaardconfiguratie: Het identificeren van code die bereikbaar is in de standaardinstellingen maar daar niet voor bedoeld is.
- Configuratie-interactie: Het vinden van combinaties van opties die onbedoeld beveiligingscontroles uitschakelen.
- Vroege bereikbaarheid: Het opsporen van complexe code die wordt uitgevoerd vóór essentiële controles zoals authenticatie.
In een onderzoek naar 25 open-source projecten ontdekte Claude 493 problemen. Een prominente casestudy is OpenSSH, waarbij Claude ontdekte dat ongeveer 4.500 regels experimentele code (ML-DSA-44) onnodig bereikbaar waren voor niet-geauthenticeerde clients. Dit leidde tot concrete patches in versie 10.6 die het aanvalsoppervlak aanzienlijk verkleinden.
De auteurs hebben deze technieken geïntegreerd in een herbruikbare 'skill' binnen de OSS-Scanner, die via drie passes codebases analyseert en suggesties doet voor het plaatsen van 'poorten' om de softwarebeveiliging structureel te verbeteren.
Gebruik van Claude om het aanvalsoppervlak van code te verkleinen
Over het afgelopen jaar hebben we veel gegevens gepubliceerd die aantonen dat geavanceerde AI-modellen meer dan in staat zijn om beveiligingskwetsbaarheden te ontdekken en te exploiteren. Het aantonen hoe voorheen onbekende kwetsbaarheden kunnen worden misbruikt, is echter slechts het begin van wat frontier AI-modellen kunnen betekenen voor cyberdefensie. In dit bericht vatten we ons initiële onderzoek samen naar geautomatiseerde analyse en reductie van het aanvalsoppervlak: het proces waarbij AI-modellen worden gebruikt om in kaart te brengen welke code bereikbaar is, om vervolgens de toegang tot alles wat een specifieke implementatie niet hoeft bloot te stellen, te verwijderen of te beperken.
Geautomatiseerde analyse en reductie van het aanvalsoppervlak kan de beveiliging van geïmplementeerde software op korte termijn aanzienlijk verbeteren. Het beveiligen van software door enkel individuele kwetsbaarheden te vinden en te verhelpen, schaalt slecht: het verhelpen van zelfs een kritieke kwetsbaarheid zegt niets over de kwetsbaarheden die overblijven. Daarentegen kan het verminderen van de bereikbaarheid van code de ernst van onbekende kwetsbaarheden verminderen, inclusief diegene die mogelijk al actief worden geëxploiteerd. Deze technieken verwijderen de onbekende kwetsbaarheden in de code niet, maar maken ze wel moeilijker bereikbaar, waardoor hun ernst afneemt. Het minimaliseren van het aanvalsoppervlak van codebases resulteert in een betere beveiliging zonder dat individuele kwetsbaarheden hoeven te worden gevonden of opgelost.
Hieronder presenteren we een voorproefje van de gegevens die we hebben verzameld door technieken voor het verkleinen van het aanvalsoppervlak toe te passen op grote open-source codebases met behulp van Claude. Ons doel is om aan te tonen dat Claude de softwarebeveiliging op een betekenisvolle en economische manier kan verbeteren via de door ons beschreven methoden. Concreet hebben we Claude ingezet op 25 projecten (in diverse talen), waarbij het model 493 problemen ontdekte. Met deze resultaten in het achterhoofd bespreken we hoe ontwikkelaars soortgelijke technieken kunnen toepassen op hun eigen code.
Methoden voor het verkleinen van het aanvalsoppervlak van codebases
Na verloop van tijd hebben softwareprojecten de neiging complexer te worden, waarbij nieuwe abstractielagen, nieuwe afhankelijkheden en nieuwe functies langzaam op elkaar worden gestapeld. Dit kan er vaak toe leiden dat software heel anders functioneert dan de oorspronkelijke ontwikkelaars hadden bedoeld. Dit is een belangrijke reden waarom aanvallers vaak succesvol zijn: zij bestuderen precies hoe een stuk code in de praktijk zich gedraagt, in plaats van hoe de ontwikkelaars het hadden bedoeld of ontworpen.
Geautomatiseerde technieken voor analyse en reductie van het aanvalsoppervlak zijn erop gericht om onnodige aanvalsoppervlakken te ontdekken en die code vervolgens achter een geschikte 'poort' (gate) te plaatsen. Dit kan inhouden dat code wordt verplaatst van:
- Pre-authenticatie naar post-authenticatie;
- 0-click naar 1-click;
- Standaard ingeschakeld (on-by-default) naar expliciet opt-in;
- Het eerste bericht van een protocol naar een dieper punt in de session state machine.
Sommige code is bedoeld om vóór deze fasen bereikbaar te zijn, maar veel code is dat niet. Gezien de complexiteit die gepaard gaat met code-wijzigingen over duizenden of miljoenen regels code, blijft onnodige blootstelling van functies vaak onopgemerkt.
In ons onderzoek hebben we ons specifiek gericht op drie methoden:
- Standaardconfiguratie (Default configuration): We identificeerden code die bereikbaar was in de geleverde standaardconfiguratie, maar die niet bedoeld was om te worden gebruikt door enige standaardfunctionaliteit.
- Configuratie-interactie (Configuration interaction): We vonden paren van opties die afzonderlijk redelijk leken, maar die problemen veroorzaakten wanneer ze samen werden geconfigureerd (bijvoorbeeld door stilletjes een beveiligingscontrole uit te schakelen, of door het gedrag van een functie ongedefinieerd te laten terwijl de code bereikbaar blijft).
- Vroege bereikbaarheid (Early reachability): We identificeerden beveiligingsgevoelige en complexe code die wordt uitgevoerd vóór een passende beveiligingscontrole (zoals authenticatie), zonder interactie van het slachtoffer, of vóór een overgang in de protocolstatus (protocol state transition).
We wilden begrijpen hoe goed Claude deze drie beschrijvingen van het aanvalsoppervlak kon gebruiken om echte problemen te ontdekken in grote en complexe codebases. We analyseerden 25 open-source projecten (met in totaal meer dan vijf miljoen regels code), geschreven in talen waaronder C, C++, Java, PHP en Python. Claude stelde een inventaris op van meer dan 17.000 configuratie-opties over deze projecten. Hiervan hadden er 3.842 betrekking op de configuratie van een controle of functie die relevant was voor de beveiliging.
Voor dit onderzoek hebben we deze open-source projecten onderverdeeld in drie brede categorieën:
- Public: Projecten die zijn gebouwd om elke gebruiker die hen kan bereiken te dienen, of om data te consumeren die zijn geschreven door partijen die zij niet kunnen identificeren (bijv. een DNS-resolver die antwoorden van upstream parseert, of een proxy die responsen van de origin parseert).
- Gated: Projecten die bedoeld zijn om geauthenticeerde gebruikers te dienen (zoals gebruikers met een wachtwoord, sleutel, certificaat of geregistreerde apparaten). De software staat nog steeds willekeurige client-aanvragen toe, maar er is geen functionaliteit beschikbaar totdat de gebruiker is geauthenticeerd.
- Private: Projecten die zijn gebouwd en geïmplementeerd voor de eigen private omgeving van de operator. In deze gevallen is het toevoegen van een controle zoals een authenticatielaag optioneel, maar valt het buiten de scope van de software.
Deze categorieën helpen om de resultaten in context te plaatsen. Zo is het verwacht dat een aanzienlijk percentage van een Public codebase bereikbaar is in de standaardconfiguratie, terwijl het tegenovergestelde geldt voor projecten in de Gated categorie.
Bevindingen van Claude
Claude vond 493 problemen met behulp van de drie bovengenoemde methoden. Enkele thema's vielen ons op in de resultaten.
Ten eerste stelde Claude vast dat alle elf gated projecten code hadden die onbedoeld bereikbaar was (hoewel deze code geen significant percentage van de totale regels code van die projecten uitmaakte). Specifiek ontdekte Claude:
- 93 onnodige pre-authenticatie-oppervlakken in de standaardconfiguratie van de gated groep;
- 37 locaties waar code werd uitgevoerd, of status werd geregistreerd, vóór authenticatie;
- 61 configuratiecombinaties die stilletjes een pre-authenticatiecontrole verzwakten die door de beheerder was geconfigureerd.
Geen van deze problemen was op zichzelf onmiddellijk exploiteerbaar, maar ze creëren een veel groter aanvalsoppervlak dan noodzakelijk is.
Ten tweede leverden de inspanningen van Claude om problemen met configuratie-interactie te beperken enkele van de meest interessante en impactvolle bevindingen op over alle projecttypen heen. Claude vond 162 beveiligingsgevoelige configuratiecombinaties die werden geaccepteerd zonder foutmelding of waarschuwing, en zonder documentatie over het verwachte gedrag van hun interactie. In 94 van die gevallen schakelde de combinatie stilletjes een beveiligingscontrole uit. De overige 68 gevallen waren inconsistenties in dezelfde beveiligingsmechanismen (bijv. een listener of login-pad bleef bereikbaar terwijl de configuratie aangaf dat dit was uitgeschakeld; twee instellingen botsten, waarbij de prioriteit afhing van hun volgorde in het configuratiebestand, of een door de beheerder geconfigureerde bescherming deed niets terwijl de code bereikbaar bleef). Hoewel sommige van deze combinaties ongebruikelijk kunnen zijn, is er niets dat een beheerder zou beletten de code op deze manier te configureren en te implementeren.
Claude vond ook één specifiek patroon dat onafhankelijk van elkaar in vier niet-gerelateerde projecten voorkwam: Een beheerder schrijft een toegangsregel voor externe clients met behulp van een hostname of een wildcard-patroon, in plaats van een IP-adres. Wanneer een client verbinding maakt, vergelijkt de server die regel met de hostname van de client. Of de server die hostname ooit leert, hangt af van een aparte optie die reverse DNS-lookups regelt (die in de meeste projecten waren uitgeschakeld). Als lookups zijn uitgeschakeld, heeft de server alleen het IP-adres van de client. De server vergelijkt de regel dan met dat adres als platte tekst. Omdat een hostname-patroon nooit overeenkomt met een IP-adres, zal een deny-regel nooit afgaan, waardoor de lijst "fail open" gaat. Sommige van de getroffen projecten vermelden in hun documentatie dat hostname-regels afhankelijk zijn van ingeschakelde DNS-lookups, maar geen enkele stelt dat een deny-lijst die op deze manier is geschreven, fail open-gedrag vertoont.
Ten derde ontdekte Claude vaak dat twee configuratie-opties op een manier botsten waardoor een beveiligingscontrole stilletjes werd overgeslagen. In één geval kon een beheerder vereisen dat elke verbindende client zijn identiteit bewijst met een certificaat. In een andere optie was de code alleen bedoeld om die controle uit te stellen tot deze nodig was, maar in werkelijkheid werd de controle volledig uitgeschakeld. Een server die geconfigureerd was om alleen vertrouwde clients te accepteren, zou dus een verbinding van iedereen accepteren. Hierdoor werd een groot deel van de request-handling code (die achter de certificaatcontrole had moeten zitten) blootgesteld aan niet-geauthenticeerde clients. De software accepteerde beide configuratie-opties samen zonder waarschuwing onder standaardinstellingen; de documentatie vermeldde nooit dat de certificaatvereiste was komen te vervallen. Deze conflicterende set configuratie-opties was al 21 jaar aanwezig in de software.
Ten slotte ontdekte Claude een probleem in een project waarbij authenticatie standaard was uitgeschakeld (en men verwachtte dat de beheerder dit zou inschakelen). De optie die TLS-clientcertificaten vereiste, werd gerespecteerd op de meeste netwerkeindpunten van het project, maar stilletjes genegeerd op enkele anderen (die hun TLS-instellingen via een pad met een andere namespace laadden). Dit betekende dat een client zonder certificaat de TLS-handshake kon voltooien en een sessie kon openen op een getroffen eindpunt. Er werd niets gelogd over de genegeerde instelling. Of de optie effect had, hing af van de namespace die de beheerder in de configuratie gebruikte. Eén vorm van de instellingsnaam werkt op elk eindpunt, maar de kortere vorm — die in de meeste voorbeelden wordt gebruikt — wordt op de getroffen eindpunten genegeerd.
Casestudy: OpenSSH
Verrassend genoeg was OpenSSH, gemeten als percentage van de totale regels code, het project waarbij Claude de grootste reductie in het aanvalsoppervlak behaalde. OpenSSH is een hoogwaardige C-codebase die beveiligde toegang op afstand biedt. Claude traceerde de input-paden van de SSH-daemon in release 10.4 en vond ongeveer 4.500 regels nieuwe en experimentele code voor ML-DSA-44, een post-quantum signatuuralgoritme, die een niet-geauthenticeerde client in de standaardconfiguratie kon bereiken. ML-DSA is standaard niet ingeschakeld, maar de code was ongeacht dat bereikbaar, zelfs wanneer een beheerder het algoritme expliciet uitsloot. De daemon parseerde welk sleuteltype de client ook stuurde (en verifieerde bij certificaten ook de ingesloten CA-signatuur). Pas daarna werd gecontroleerd of dat sleuteltype was toegestaan. Er is geen goede reden waarom deze complexe, memory-unsafe code bereikbaar zou moeten zijn wanneer deze niet is ingeschakeld via de configuratie. Die 4.500 regels code in ML-DSA-44 vormen ongeveer 16% van de pre-authenticatie code van OpenSSH in een standaard sshd. We hebben dit gemeld aan de OpenSSH-ontwikkelaars samen met patches. Release 10.5 verplaatste de controle naar een moment vóór het parsen.
Claude merkte vervolgens twee hiaten op in de controle van versie 10.5. Het eerste was een mismatch tussen wat de client claimde en wat deze verstuurde. De controle keek naar de door de client geadverteerde algoritmenaam, maar de parser werd gekozen op basis van een type-string die in de key blob was ingebed. Een client kon ssh-ed25519 adverteren, de controle passeren, en toch een ML-DSA-sleutel sturen die geparsed zou worden.
Het tweede hiaat zat in de certificaten van de 10.5-controle. Certificaatsleuteltypes waren standaard ingeschakeld. Bij een door een aanvaller verstrekt certificaat zou sshd de ingebedde CA-publieke sleutel deserialiseren en een volledige signatuurverificatie uitvoeren met deze sleutel voor elk ondersteund algoritme, vóórdat de configuratie werd geraadpleegd. Het pad voor de gebruikerssleutelsignatuur was correct afgeschermd achter de lijst met publieke sleutels die verbinding mochten maken met de server, maar het CA-signatuurpad was dat niet. Hierdoor werd elke publieke sleutelsignatuur-verifieerder in het binary bereikbaar voor elke client die een sleuteluitwisseling kon voltooien. We hebben een proof-of-concept gebouwd en via verschillende iteraties aan een oplossing gewerkt met de maintainers. De resulterende wijziging plaatste de controles binnen de parser zelf. Het gecodeerde sleuteltype en het CA-signatuuralgoritme van het certificaat worden nu vergeleken met de geconfigureerde allow-lijsten voordat de corresponderende deserialisatie of signatuurverificatie plaatsvindt.
Deze fix verwijderde ongeveer een vijfde van de OpenSSH-code die een niet-geauthenticeerde client voorheen kon bereiken in een standaard build. Bijna alles daarvan was de nieuwe ML-DSA-code, die nu onbereikbaar is, zelfs voor een client die liegt over zijn sleuteltype of een ML-DSA CA-sleutel verbergt in een verder acceptabel certificaat. Certificaten die zijn ondertekend met een toegestaan CA-algoritme worden nog steeds geparsed en geverifieerd, maar de controle vindt nu plaats vóór het parsen. De maintainers hebben de beschreven wijzigingen doorgevoerd in versie 10.6.
OpenSSH is een van de meest zwaar geauditeerde codebases ter wereld. Als onnodige bereikbaarheid daar overleeft, kan het overal overleven. Dit suggereert dat het verkleinen van het aanvalsoppervlak van codebases waarschijnlijk vruchten afwerpt bij veel belangrijke projecten.
Conclusie
Het is wellicht onmogelijk om te meten hoeveel onbekende kwetsbaarheden er in een willekeurige codebase zitten. En er is voldoende data die aantoont dat aanvallers deze kwetsbaarheden met genoeg tijd zullen vinden (zeker als ze zijn uitgerust met frontier AI-modellen). Maar een verdediger die onnodig aanvalsoppervlak in hun code vermindert, verkleint het risico van alle onbekende kwetsbaarheden in die code in één keer — inclusief diegene die al stilletjes worden geëxploiteerd. OpenSSH is een van de meest geauditeerde C-codebases ter wereld, en toch bevatte het ongeveer 4.500 regels experimentele signatuur-parsing code die door een aanvaller bereikt kon worden vóór elke configuratiecontrole.
We hebben de beschreven technieken voor het verkleinen van het aanvalsoppervlak gecombineerd in één herbruikbare Claude-skill, die we integreren in OSS-Scanner. De skill voert drie passes uit op een codebase. Elke pass begint opnieuw (met een leeg contextvenster), behalve voor een kort stukje context dat wordt ontvangen van de vorige pass.
- Eerste pass: De skill kijkt of er code is die door de standaardconfiguratie bereikbaar is, maar die niet wordt gebruikt door enige beoogde functionaliteit.
- Tweede pass: Er wordt gekeken naar de code die draait vóór harde poorten (zoals authenticatie) of vóór entry points van de protocol state machine, in elke configuratie.
- Derde pass: De skill beoordeelt welke combinaties van configuraties stilletjes een beveiligingscontrole uitschakelen of de effectiviteit ervan verminderen.
Bij elke pass maakt Claude een inventaris van de entry points uit de code en bevestigt het elke bevinding met een dynamische trace van het programma. Voor bevindingen in de standaardconfiguratie ontwerpt en implementeert Claude een poort en zorgt ervoor dat dit geen wijziging veroorzaakt in het standaardgedrag van het programma. Dit gebeurt door de eigen testsuite van het project (samen met een black-box regressiesuite) uit te voeren tegen de baseline; gemodificeerde builds moeten identieke resultaten geven. Elke poort die een niet-standaardconfiguratie zou wijzigen, wordt apart gezet voor een menselijke beslissing. Voor de andere twee passes stelt Claude wijzigingen voor, zoals het herordenen van een configuratiecontrole, het toevoegen van een guard om statusvolgorde af te dwingen, of het weigeren van de combinatie bij het laden van de configuratie. Zelfs zonder deze specifieke skill te gebruiken, denken we dat de hier beschreven brede methodologie effectief is.
De technieken in dit bericht bieden slechts een zeer beperkt beeld van wat mogelijk is bij het verkleinen van het aanvalsoppervlak. Zo is Claude ook in staat om runtime-logs te analyseren en te vergelijken met configuraties om te garanderen dat alleen de benodigde functionaliteit is ingeschakeld: het uitschakelen van ongebruikte parsers, legacy-protocollen en dashboards vermindert het beveiligingsrisico tegen lage kosten.
We moedigen organisaties aan om Claude te gebruiken om het aanvalsoppervlak van de software waar zij afhankelijk van zijn te analyseren en te verkleinen. We verwachten dat dit een van de meest praktische manieren is voor ontwikkelaars om de beveiliging van de code waarop de wereld al draait, meetbaar te verbeteren.
Gebruik van Claude om het aanvalsoppervlak van code te verkleinen
Over het afgelopen jaar hebben we veel gegevens gepubliceerd die aantonen dat geavanceerde AI-modellen meer dan in staat zijn om beveiligingskwetsbaarheden te ontdekken en te exploiteren. Het aantonen hoe voorheen onbekende kwetsbaarheden kunnen worden misbruikt, is echter slechts het begin van wat frontier AI-modellen kunnen betekenen voor cyberdefensie. In dit bericht vatten we ons initiële onderzoek samen naar geautomatiseerde analyse en reductie van het aanvalsoppervlak: het proces waarbij AI-modellen worden gebruikt om in kaart te brengen welke code bereikbaar is, om vervolgens de toegang tot alles wat een specifieke implementatie niet hoeft bloot te stellen, te verwijderen of te beperken.
Geautomatiseerde analyse en reductie van het aanvalsoppervlak kan de beveiliging van geïmplementeerde software op korte termijn aanzienlijk verbeteren. Het beveiligen van software door enkel individuele kwetsbaarheden te vinden en te verhelpen, schaalt slecht: het verhelpen van zelfs een kritieke kwetsbaarheid zegt niets over de kwetsbaarheden die overblijven. Daarentegen kan het verminderen van de bereikbaarheid van code de ernst van onbekende kwetsbaarheden verminderen, inclusief diegene die mogelijk al actief worden geëxploiteerd. Deze technieken verwijderen de onbekende kwetsbaarheden in de code niet, maar maken ze wel moeilijker bereikbaar, waardoor hun ernst afneemt. Het minimaliseren van het aanvalsoppervlak van codebases resulteert in een betere beveiliging zonder dat individuele kwetsbaarheden hoeven te worden gevonden of opgelost.
Hieronder presenteren we een voorproefje van de gegevens die we hebben verzameld door technieken voor het verkleinen van het aanvalsoppervlak toe te passen op grote open-source codebases met behulp van Claude. Ons doel is om aan te tonen dat Claude de softwarebeveiliging op een betekenisvolle en economische manier kan verbeteren via de door ons beschreven methoden. Concreet hebben we Claude ingezet op 25 projecten (in diverse talen), waarbij het model 493 problemen ontdekte. Met deze resultaten in het achterhoofd bespreken we hoe ontwikkelaars soortgelijke technieken kunnen toepassen op hun eigen code.
Methoden voor het verkleinen van het aanvalsoppervlak van codebases
Na verloop van tijd hebben softwareprojecten de neiging complexer te worden, waarbij nieuwe abstractielagen, nieuwe afhankelijkheden en nieuwe functies langzaam op elkaar worden gestapeld. Dit kan er vaak toe leiden dat software heel anders functioneert dan de oorspronkelijke ontwikkelaars hadden bedoeld. Dit is een belangrijke reden waarom aanvallers vaak succesvol zijn: zij bestuderen precies hoe een stuk code in de praktijk zich gedraagt, in plaats van hoe de ontwikkelaars het hadden bedoeld of ontworpen.
Geautomatiseerde technieken voor analyse en reductie van het aanvalsoppervlak zijn erop gericht om onnodige aanvalsoppervlakken te ontdekken en die code vervolgens achter een geschikte 'poort' (gate) te plaatsen. Dit kan inhouden dat code wordt verplaatst van:
- Pre-authenticatie naar post-authenticatie;
- 0-click naar 1-click;
- Standaard ingeschakeld (on-by-default) naar expliciet opt-in;
- Het eerste bericht van een protocol naar een dieper punt in de session state machine.
Sommige code is bedoeld om vóór deze fasen bereikbaar te zijn, maar veel code is dat niet. Gezien de complexiteit die gepaard gaat met code-wijzigingen over duizenden of miljoenen regels code, blijft onnodige blootstelling van functies vaak onopgemerkt.
In ons onderzoek hebben we ons specifiek gericht op drie methoden:
- Standaardconfiguratie (Default configuration): We identificeerden code die bereikbaar was in de geleverde standaardconfiguratie, maar die niet bedoeld was om te worden gebruikt door enige standaardfunctionaliteit.
- Configuratie-interactie (Configuration interaction): We vonden paren van opties die afzonderlijk redelijk leken, maar die problemen veroorzaakten wanneer ze samen werden geconfigureerd (bijvoorbeeld door stilletjes een beveiligingscontrole uit te schakelen, of door het gedrag van een functie ongedefinieerd te laten terwijl de code bereikbaar blijft).
- Vroege bereikbaarheid (Early reachability): We identificeerden beveiligingsgevoelige en complexe code die wordt uitgevoerd vóór een passende beveiligingscontrole (zoals authenticatie), zonder interactie van het slachtoffer, of vóór een overgang in de protocolstatus (protocol state transition).
We wilden begrijpen hoe goed Claude deze drie beschrijvingen van het aanvalsoppervlak kon gebruiken om echte problemen te ontdekken in grote en complexe codebases. We analyseerden 25 open-source projecten (met in totaal meer dan vijf miljoen regels code), geschreven in talen waaronder C, C++, Java, PHP en Python. Claude stelde een inventaris op van meer dan 17.000 configuratie-opties over deze projecten. Hiervan hadden er 3.842 betrekking op de configuratie van een controle of functie die relevant was voor de beveiliging.
Voor dit onderzoek hebben we deze open-source projecten onderverdeeld in drie brede categorieën:
- Public: Projecten die zijn gebouwd om elke gebruiker die hen kan bereiken te dienen, of om data te consumeren die zijn geschreven door partijen die zij niet kunnen identificeren (bijv. een DNS-resolver die antwoorden van upstream parseert, of een proxy die responsen van de origin parseert).
- Gated: Projecten die bedoeld zijn om geauthenticeerde gebruikers te dienen (zoals gebruikers met een wachtwoord, sleutel, certificaat of geregistreerde apparaten). De software staat nog steeds willekeurige client-aanvragen toe, maar er is geen functionaliteit beschikbaar totdat de gebruiker is geauthenticeerd.
- Private: Projecten die zijn gebouwd en geïmplementeerd voor de eigen private omgeving van de operator. In deze gevallen is het toevoegen van een controle zoals een authenticatielaag optioneel, maar valt het buiten de scope van de software.
Deze categorieën helpen om de resultaten in context te plaatsen. Zo is het verwacht dat een aanzienlijk percentage van een Public codebase bereikbaar is in de standaardconfiguratie, terwijl het tegenovergestelde geldt voor projecten in de Gated categorie.
Bevindingen van Claude
Claude vond 493 problemen met behulp van de drie bovengenoemde methoden. Enkele thema's vielen ons op in de resultaten.
Ten eerste stelde Claude vast dat alle elf gated projecten code hadden die onbedoeld bereikbaar was (hoewel deze code geen significant percentage van de totale regels code van die projecten uitmaakte). Specifiek ontdekte Claude:
- 93 onnodige pre-authenticatie-oppervlakken in de standaardconfiguratie van de gated groep;
- 37 locaties waar code werd uitgevoerd, of status werd geregistreerd, vóór authenticatie;
- 61 configuratiecombinaties die stilletjes een pre-authenticatiecontrole verzwakten die door de beheerder was geconfigureerd.
Geen van deze problemen was op zichzelf onmiddellijk exploiteerbaar, maar ze creëren een veel groter aanvalsoppervlak dan noodzakelijk is.
Ten tweede leverden de inspanningen van Claude om problemen met configuratie-interactie te beperken enkele van de meest interessante en impactvolle bevindingen op over alle projecttypen heen. Claude vond 162 beveiligingsgevoelige configuratiecombinaties die werden geaccepteerd zonder foutmelding of waarschuwing, en zonder documentatie over het verwachte gedrag van hun interactie. In 94 van die gevallen schakelde de combinatie stilletjes een beveiligingscontrole uit. De overige 68 gevallen waren inconsistenties in dezelfde beveiligingsmechanismen (bijv. een listener of login-pad bleef bereikbaar terwijl de configuratie aangaf dat dit was uitgeschakeld; twee instellingen botsten, waarbij de prioriteit afhing van hun volgorde in het configuratiebestand, of een door de beheerder geconfigureerde bescherming deed niets terwijl de code bereikbaar bleef). Hoewel sommige van deze combinaties ongebruikelijk kunnen zijn, is er niets dat een beheerder zou beletten de code op deze manier te configureren en te implementeren.
Claude vond ook één specifiek patroon dat onafhankelijk van elkaar in vier niet-gerelateerde projecten voorkwam: Een beheerder schrijft een toegangsregel voor externe clients met behulp van een hostname of een wildcard-patroon, in plaats van een IP-adres. Wanneer een client verbinding maakt, vergelijkt de server die regel met de hostname van de client. Of de server die hostname ooit leert, hangt af van een aparte optie die reverse DNS-lookups regelt (die in de meeste projecten waren uitgeschakeld). Als lookups zijn uitgeschakeld, heeft de server alleen het IP-adres van de client. De server vergelijkt de regel dan met dat adres als platte tekst. Omdat een hostname-patroon nooit overeenkomt met een IP-adres, zal een deny-regel nooit afgaan, waardoor de lijst "fail open" gaat. Sommige van de getroffen projecten vermelden in hun documentatie dat hostname-regels afhankelijk zijn van ingeschakelde DNS-lookups, maar geen enkele stelt dat een deny-lijst die op deze manier is geschreven, fail open-gedrag vertoont.
Ten derde ontdekte Claude vaak dat twee configuratie-opties op een manier botsten waardoor een beveiligingscontrole stilletjes werd overgeslagen. In één geval kon een beheerder vereisen dat elke verbindende client zijn identiteit bewijst met een certificaat. In een andere optie was de code alleen bedoeld om die controle uit te stellen tot deze nodig was, maar in werkelijkheid werd de controle volledig uitgeschakeld. Een server die geconfigureerd was om alleen vertrouwde clients te accepteren, zou dus een verbinding van iedereen accepteren. Hierdoor werd een groot deel van de request-handling code (die achter de certificaatcontrole had moeten zitten) blootgesteld aan niet-geauthenticeerde clients. De software accepteerde beide configuratie-opties samen zonder waarschuwing onder standaardinstellingen; de documentatie vermeldde nooit dat de certificaatvereiste was komen te vervallen. Deze conflicterende set configuratie-opties was al 21 jaar aanwezig in de software.
Ten slotte ontdekte Claude een probleem in een project waarbij authenticatie standaard was uitgeschakeld (en men verwachtte dat de beheerder dit zou inschakelen). De optie die TLS-clientcertificaten vereiste, werd gerespecteerd op de meeste netwerkeindpunten van het project, maar stilletjes genegeerd op enkele anderen (die hun TLS-instellingen via een pad met een andere namespace laadden). Dit betekende dat een client zonder certificaat de TLS-handshake kon voltooien en een sessie kon openen op een getroffen eindpunt. Er werd niets gelogd over de genegeerde instelling. Of de optie effect had, hing af van de namespace die de beheerder in de configuratie gebruikte. Eén vorm van de instellingsnaam werkt op elk eindpunt, maar de kortere vorm — die in de meeste voorbeelden wordt gebruikt — wordt op de getroffen eindpunten genegeerd.
Casestudy: OpenSSH
Verrassend genoeg was OpenSSH, gemeten als percentage van de totale regels code, het project waarbij Claude de grootste reductie in het aanvalsoppervlak behaalde. OpenSSH is een hoogwaardige C-codebase die beveiligde toegang op afstand biedt. Claude traceerde de input-paden van de SSH-daemon in release 10.4 en vond ongeveer 4.500 regels nieuwe en experimentele code voor ML-DSA-44, een post-quantum signatuuralgoritme, die een niet-geauthenticeerde client in de standaardconfiguratie kon bereiken. ML-DSA is standaard niet ingeschakeld, maar de code was ongeacht dat bereikbaar, zelfs wanneer een beheerder het algoritme expliciet uitsloot. De daemon parseerde welk sleuteltype de client ook stuurde (en verifieerde bij certificaten ook de ingesloten CA-signatuur). Pas daarna werd gecontroleerd of dat sleuteltype was toegestaan. Er is geen goede reden waarom deze complexe, memory-unsafe code bereikbaar zou moeten zijn wanneer deze niet is ingeschakeld via de configuratie. Die 4.500 regels code in ML-DSA-44 vormen ongeveer 16% van de pre-authenticatie code van OpenSSH in een standaard sshd. We hebben dit gemeld aan de OpenSSH-ontwikkelaars samen met patches. Release 10.5 verplaatste de controle naar een moment vóór het parsen.
Claude merkte vervolgens twee hiaten op in de controle van versie 10.5. Het eerste was een mismatch tussen wat de client claimde en wat deze verstuurde. De controle keek naar de door de client geadverteerde algoritmenaam, maar de parser werd gekozen op basis van een type-string die in de key blob was ingebed. Een client kon ssh-ed25519 adverteren, de controle passeren, en toch een ML-DSA-sleutel sturen die geparsed zou worden.
Het tweede hiaat zat in de certificaten van de 10.5-controle. Certificaatsleuteltypes waren standaard ingeschakeld. Bij een door een aanvaller verstrekt certificaat zou sshd de ingebedde CA-publieke sleutel deserialiseren en een volledige signatuurverificatie uitvoeren met deze sleutel voor elk ondersteund algoritme, vóórdat de configuratie werd geraadpleegd. Het pad voor de gebruikerssleutelsignatuur was correct afgeschermd achter de lijst met publieke sleutels die verbinding mochten maken met de server, maar het CA-signatuurpad was dat niet. Hierdoor werd elke publieke sleutelsignatuur-verifieerder in het binary bereikbaar voor elke client die een sleuteluitwisseling kon voltooien. We hebben een proof-of-concept gebouwd en via verschillende iteraties aan een oplossing gewerkt met de maintainers. De resulterende wijziging plaatste de controles binnen de parser zelf. Het gecodeerde sleuteltype en het CA-signatuuralgoritme van het certificaat worden nu vergeleken met de geconfigureerde allow-lijsten voordat de corresponderende deserialisatie of signatuurverificatie plaatsvindt.
Deze fix verwijderde ongeveer een vijfde van de OpenSSH-code die een niet-geauthenticeerde client voorheen kon bereiken in een standaard build. Bijna alles daarvan was de nieuwe ML-DSA-code, die nu onbereikbaar is, zelfs voor een client die liegt over zijn sleuteltype of een ML-DSA CA-sleutel verbergt in een verder acceptabel certificaat. Certificaten die zijn ondertekend met een toegestaan CA-algoritme worden nog steeds geparsed en geverifieerd, maar de controle vindt nu plaats vóór het parsen. De maintainers hebben de beschreven wijzigingen doorgevoerd in versie 10.6.
OpenSSH is een van de meest zwaar geauditeerde codebases ter wereld. Als onnodige bereikbaarheid daar overleeft, kan het overal overleven. Dit suggereert dat het verkleinen van het aanvalsoppervlak van codebases waarschijnlijk vruchten afwerpt bij veel belangrijke projecten.
Conclusie
Het is wellicht onmogelijk om te meten hoeveel onbekende kwetsbaarheden er in een willekeurige codebase zitten. En er is voldoende data die aantoont dat aanvallers deze kwetsbaarheden met genoeg tijd zullen vinden (zeker als ze zijn uitgerust met frontier AI-modellen). Maar een verdediger die onnodig aanvalsoppervlak in hun code vermindert, verkleint het risico van alle onbekende kwetsbaarheden in die code in één keer — inclusief diegene die al stilletjes worden geëxploiteerd. OpenSSH is een van de meest geauditeerde C-codebases ter wereld, en toch bevatte het ongeveer 4.500 regels experimentele signatuur-parsing code die door een aanvaller bereikt kon worden vóór elke configuratiecontrole.
We hebben de beschreven technieken voor het verkleinen van het aanvalsoppervlak gecombineerd in één herbruikbare Claude-skill, die we integreren in OSS-Scanner. De skill voert drie passes uit op een codebase. Elke pass begint opnieuw (met een leeg contextvenster), behalve voor een kort stukje context dat wordt ontvangen van de vorige pass.
- Eerste pass: De skill kijkt of er code is die door de standaardconfiguratie bereikbaar is, maar die niet wordt gebruikt door enige beoogde functionaliteit.
- Tweede pass: Er wordt gekeken naar de code die draait vóór harde poorten (zoals authenticatie) of vóór entry points van de protocol state machine, in elke configuratie.
- Derde pass: De skill beoordeelt welke combinaties van configuraties stilletjes een beveiligingscontrole uitschakelen of de effectiviteit ervan verminderen.
Bij elke pass maakt Claude een inventaris van de entry points uit de code en bevestigt het elke bevinding met een dynamische trace van het programma. Voor bevindingen in de standaardconfiguratie ontwerpt en implementeert Claude een poort en zorgt ervoor dat dit geen wijziging veroorzaakt in het standaardgedrag van het programma. Dit gebeurt door de eigen testsuite van het project (samen met een black-box regressiesuite) uit te voeren tegen de baseline; gemodificeerde builds moeten identieke resultaten geven. Elke poort die een niet-standaardconfiguratie zou wijzigen, wordt apart gezet voor een menselijke beslissing. Voor de andere twee passes stelt Claude wijzigingen voor, zoals het herordenen van een configuratiecontrole, het toevoegen van een guard om statusvolgorde af te dwingen, of het weigeren van de combinatie bij het laden van de configuratie. Zelfs zonder deze specifieke skill te gebruiken, denken we dat de hier beschreven brede methodologie effectief is.
De technieken in dit bericht bieden slechts een zeer beperkt beeld van wat mogelijk is bij het verkleinen van het aanvalsoppervlak. Zo is Claude ook in staat om runtime-logs te analyseren en te vergelijken met configuraties om te garanderen dat alleen de benodigde functionaliteit is ingeschakeld: het uitschakelen van ongebruikte parsers, legacy-protocollen en dashboards vermindert het beveiligingsrisico tegen lage kosten.
We moedigen organisaties aan om Claude te gebruiken om het aanvalsoppervlak van de software waar zij afhankelijk van zijn te analyseren en te verkleinen. We verwachten dat dit een van de meest praktische manieren is voor ontwikkelaars om de beveiliging van de code waarop de wereld al draait, meetbaar te verbeteren.