Testing Security

Security. Een Engels woord van 8 letters, maar met een grote betekenis voor IT’ers, althans dat zou het moeten hebben. Veelal wordt over security pas laat in het ontwikkeltraject nagedacht. Als er dan al over nagedacht wordt, wordt er veelal alleen gekeken naar toegang tot de applicatie, authenticatie en autorisatie. Echter is het niet onbelangrijk om er meer rekening mee te houden.

Auteur: Marten Deinum

Tegenwoordig zijn hackers steeds vaker bezig met het zoeken van kwetsbaarheden in bestaande applicaties, besturingssystemen en hardware (en alles wat daar tussenin zit). Middels deze kwetsbaarheden proberen ze zich dan toegang te verschaffen tot gegevens die ze kunnen verkopen, gebruiken als chantagemiddel of om fraudeleuze transacties te doen.

Wanneer we gaan nadenken over Security van onze applicatie, moeten we niet alleen kijken naar authenticatie en autorisatie, maar moeten we breder kijken. Wanneer we een applicatie in ogenschouw nemen, zijn ook de volgende zaken relevant:
– Code analyse
– Dependencies van de applicatie
– Security Headers
– SSL Certificaten

Gelukkig hebben we tegenwoordig een CI/CD pipeline en kunnen we veel van deze taken automatiseren en periodiek laten uitvoeren. Ook helpen tools zoals SonarQube met het in de gaten houden van bepaalde zwakheden in de code, configuratie en dependencies, alleen is dit wel afhankelijk van de versie van SonarQube die in gebruik is. In dit artikel gaan we in op een aantal Open Source en gratis mogelijkheden om ook de security van onze applicatie code, configuratie en dependencies in de gaten te houden.

We zullen gebruikmaken van een applicatie die gebouwd wordt via Maven via een CI pipeline gemaakt met CircleCI. Uiteraard kunnen deze scans en tools ook gebruikt worden met bijvoorbeeld Gradle en andere CI oplossingen zoals Jenkins, TravisCI en Gitlab. De code behorende bij dit artikel is te vinden op GitHub.

Code analyse

Ook de eigen code kan kwetsbaarheden bevatten die misbruikt kunnen worden. Om de code te controleren op zulke constructies, kan een plugin als de SpotBugs plugin helpen. Deze plugin zelf is ook weer uit te breiden met plugins. Er is zelfs een specifieke extensie voor het opsporen van security issues in code: Find Security Bugs.

<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <version>4.0.4</version>
    <configuration>
        <effort>Max</effort>
        <threshold>Low</threshold>
        <failOnError>true</failOnError>
        <plugins>
            <plugin>
                <groupId>com.h3xstream.findsecbugs</groupId>
                <artifactId>findsecbugs-plugin</artifactId>
                <version>1.10.1</version>
            </plugin>
        </plugins>
    </configuration>
</plugin>

Met deze toevoeging aan de pom.xml kan de code geanalyseerd op bekende kwetsbaarheden en zal het bouwen van de software falen. Het gebruiken van de plugin kan nu door het uitvoeren van mvn spotbugs:check waarna de code geanalyseerd wordt. Wanneer we dit opnemen als stap in onze CI pipeline, zien we dat de build opeens faalt.

Dependencies

Een applicatie gebruikt vaak verschillende dependencies. Is het niet rechtstreeks, dan wel via de applicatieserver waar gebruik van wordt gemaakt. Verouderde dependencies kunnen lekken bevatten of zelfs bepaalde combinaties van dependencies. Deze lekken kunnen dan gebruikt worden om toegang te verschaffen tot het systeem. Een goed voorbeeld hiervan is de Equifax Data Breach van begin 2017. Hier ontdekten hackers dat er gebruikgemaakt werd van een oude versie van Apache Struts. Deze versie bevatte een lek dat gebruikt is om toegang te verschaffen tot de systemen, met als gevolg dat er data van 147 miljoen Amerikanen op straat kwam te liggen.

OWASP, wat de afkorting is voor Open Web Application Security Group, heeft diverse tools beschikbaar om de veiligheid van je applicatie te testen. Een van deze tools is een plugin voor onder meer Maven. De Dependency Check Plugin, deze plugin downloadt een lijst van bekende zwakheden in versies van dependencies (zoals de Struts dependency destijds in gebruik bij Equifax) en controleert vervolgens de gebruikte dependencies tegen deze lijst. De lijst van zwakheden, zogenaamde CVE’s, is een openbare lijst en is bijvoorbeeld te vinden op https://nvd.nist.gov.

<plugin>
    <groupId>org.owasp</groupId>
    <artifactId>dependency-check-maven</artifactId>
    <version>6.0.1</version>
    <configuration>
        <failBuildOnAnyVulnerability>true</failBuildOnAnyVulnerability>
    </configuration>
</plugin>

Net als de eerder genoemde SpotBugs plugin kan nu deze plugin gebruikt worden, dit kan door mvn dependency-check:check uit te voeren. De eerste keer kan dit een tijd duren, omdat eerst de database met alle bekende kwetsbaarheden wordt gedownload. Alle volgende keren wordt de database slechts bijgewerkt.

Afbeelding 1. Dependency Check.

Zoals te zien op afbeelding 1 faalt de build, dit omdat we een aantal dependencies gebruiken waarin kwetsbaarheden zitten en momenteel gebruikt de applicatie een oude versie van jQuery met de nodige kwetsbaarheden. De oplossing in dit geval is het upgraden van de dependencies en het aanpassen van de JavaScript opdat we jQuery niet meer nodig zijn.

Afbeelding 2

Zoals te zien in afbeelding 2 wordt er een lijst met dependencies gegenereerd met de zwakheden erin en ook welke CVE’s het betreft. Deze zijn dan op de eerder genoemde website terug te lezen en kan er besloten worden wat er met de melding moet gebeuren. Het kan namelijk zijn dat er bijvoorbeeld een dependency in de applicatie zit die niet gebruikt wordt, dan kun je de melding negeren of de dependency uitsluiten. Wat wel belangrijk bij het gebruik van deze plugin is dat deze check periodiek wordt uitgevoerd en eigenlijk ook voor software waar niet actief op wordt ontwikkeld. Het is dus raadzaam om bijvoorbeeld een CI job in te richten die wekelijks een scan doet van de dependencies, zodat een situatie zoals de eerder genoemde Equifax Data Breach niet meer voorkomt.

Headers

Ook browsers kunnen helpen bij het veiliger maken van applicaties, echter moeten deze zaken vaak expliciet aangezet worden. Zo zijn er bepaalde headers die het moeilijker maken om bepaalde aanvallen uit te voeren of om cookies aan te passen. Enkele voorbeelden zijn de X-Frame-Options, X-XSS-Protection en Strict-Transport-Security. Naast deze headers kan er nog meer gecontroleerd worden, zoals het mixen van HTTP en HTTPS resources, OpenSSL HeartBleed of een kwestbare JavaScript library. Om deze controles uit te voeren kan er gebruikgemaakt worden van de ZAP Baseline Scan. Deze scan maakt gebruik van de Zed Attack Proxy, kortweg ZAP genoemd, om kwetsbaarheden in een website te ontdekken.

Deze tool analyseert verkeer vanaf een URL en kijkt waar er nog verbetering mogelijk is. Ook is het mogelijk om geautomatiseerd een penetratie test (pen-test) uit te voeren middels ZAP. De ZAP kan ook gebruikt worden als standalone applicatie voor gebruik op je eigen werkplek, maar ook automatisch via een Docker image voor gebruik in een CI/CD pipeline.

Middels een configuratiebestand kun je aangeven hoe er gereageerd moet worden op bepaalde kwetsbaarheden. Standaard krijg je alleen maar warnings. Echter kan er ook voor gekozen worden om bepaalde zaken te negeren of om explicit te falen.

# zap-baseline rule configuration file
# Change WARN to IGNORE to ignore rule or FAIL to fail if rule matches
# Only the rule identifiers are used - the names are just for info
# You can add your own messages to each rule by appending them after a tab on each line.
10003   WARN    (Vulnerable JS Library)
10010   FAIL    (Cookie No HttpOnly Flag)
10011   FAIL    (Cookie Without Secure Flag)
10015   FAIL    (Incomplete or No Cache-control and Pragma HTTP Header Set)
10016   FAIL    (Web Browser XSS Protection Not Enabled)
10017   FAIL    (Cross-Domain JavaScript Source File Inclusion)
10019   FAIL    (Content-Type Header Missing)
10020   FAIL    (X-Frame-Options Header)
10021   FAIL    (X-Content-Type-Options Header Missing)
10023   WARN    (Information Disclosure - Debug Error Messages)
10024   WARN    (Information Disclosure - Sensitive Information in URL)
10025   WARN    (Information Disclosure - Sensitive Information in HTTP Referrer Header)

In de voor dit artikel gebruikte configuratie willen we falen op het ontbreken van bepaalde headers en voor het niet goed beveiligen van cookies. Deze regels staan dan ook op FAIL.

Om dit te kunnen uitvoeren via Docker voer je het volgende uit op de command-line. De eerste 2 commando’s maken een volume aan met het configuratiebestand, welke in stap 3 gebruikt wordt om de proxy zijn werk te laten doen. Uiteraard is dit dan ook redelijk eenvoudig uit te voeren op de CI/CD server.

docker create -v /zap/wrk --name zapwrk alpine:3.12 /bin/true 
docker cp ./zap-baseline.conf zapwrk:/zap/wrk 
docker pull owasp/zap2docker-weekly && \
              docker run \
                --volumes-from zapwrk \
                -t owasp/zap2docker-weekly zap-baseline.py -d -c zap-baseline.conf -t https://invoicer.cfapps.io
  • Aanmaken van een docker volume
  • Kopiëren van configuratie bestand naar volume
  • Uitvoeren van de scan met het configuratiebestand uit het volume
Afbeelding 3. Zap baseline.

Uit afbeelding 3 blijkt dat de ZAP Baseline controle heeft gedraaid en is gefaald. In de logging zien we precies wat er aan de hand is.

Afbeelding 4. Baseline log.

De logging toont aan dat er een aantal headers niet gezet is waarvan we in de configuratie aangegeven hebben dat deze wel gezet zouden moeten zijn. De applicatie moet aangepast worden zodat deze headers wel gezet worden. Nu betreft dit een op Spring Boot gebaseerde applicatie. Het toevoegen van Spring Security als dependency is voldoende om de ZAP Baseline controle tevreden te stellen.

Afbeelding 5. Baseline check 2.

Na het toevoegen van Spring Security als dependency in onze applicatie, gaat nu de ZAP Baseline controle goed, echter faalt nu weer de depenendency check in verband met een geconstateerde kwetsbaarheid in Spring Security. In dit geval betreft het CVE-2018-1258 en na lezen van dit rapport is dit een false positive. Middels configuratie van de OWASP Dependency Check zou je deze false positive kunnen onderdrukken.

Certificaten

Tegenwoordig zou eigenlijk al het HTTP verkeer via SSL moeten gaan, dit is helaas nog niet altijd het geval. Echter ligt de focus wel steeds meer op SSL verkeer en hierdoor ligt het ook meer onder het vergrootglas van hackers. Zo worden bijvoorbeeld kwetsbaarheden in encrypte methoden en ciphers geprobeerd te vinden. Zo zijn er ook al een aantal ciphers tot zwak bestempeld en zouden niet meer gebruikt moeten worden. Eigenlijk zou ook periodiek de inrichting van de server op het gebied van SSL getest moeten worden. Dit testen kan uitgevoerd worden middels een tool genaamd Mozilla TLS Observatory. De tool analyseert een URL en dan voornamelijk op het gebied van SSL, en hangt hier uiteindelijk een score aan. Hoe hoger de score, hoe beter het resultaat.

Deze tool is geschreven in Go en dit moet dan ook geïnstalleerd zijn. Een ander alternatief is dat er gebruikgemaakt wordt van docker om deze controle uit te voeren. Op de CI server gebruiken we een docker image met Go en installeren we de tlsobs tool en voeren deze vervolgens uit. De onderstaande stappen worden uitgevoerd en kunnen ook lokaal, mits Go aanwezig is, uitgevoerd worden.

go get github.com/mozilla/tls-observatory/tlsobs 
tlsobs invoicer.cfapps.io

– Installeren van ‘tlsobs’ via Go
– Uitvoeren de tlsobs om het betreffende domein te scannen

Afbeelding 6.

Uit de scan blijkt dat de inrichting een Grade A (93 van de 100 punten) krijgen, wat dus goed is. Tevens geeft de scan aan dat er nog een aantal zaken te verbeteren zijn, zoals het type certificaat, het verwijderen van een aantal verouderde ciphers en toevoegen van een aantal nieuwe ciphers.

Samenvatting

Security is iets wat in het ontwikkeltraject, maar ook daarna nog van belang is. Security beperkt zich tevens niet tot alleen authenticatie en autorisatie, maar ook detecteren van kwetsbaarheden in code, dependencies en inrichting van de server. Gelukkig leven we in een tijdperk waarin we geholpen kunnen worden door onze CI/CD pipelines en (gratis) tools die dit werk voor ons uit handen nemen. Voor het analyseren van code is SpotBugs een oplossing waar voor het analyseren van kwetsbaarheden in depenencies de OWASP Dependency Checker een oplossing biedt. Voor het testen van de applicatie kan er middels de ZAP Proxy een aanval uitgevoerd worden en het resultaat geanalyseerd worden. Tot slot kan door gebruik van de Mozilla TLS Observatory tool de inrichting van SSL op de server onderzocht worden. Deze tooling is beschikbaar tijdens het ontwikkelen van applicaties, maar het is ook belangrijk dat applicaties die “uit ontwikkeld zijn” ook in de gaten gehouden worden. Dit om gevallen zoals de Equifax Data Breach niet te laten voorkomen. Tot slot de lijst met tooling is vele malen uitgebreider dan we hier kunnen behandelen. Er zijn ook tools als die van Snyk beschikbaar, tevens heeft GitHub tegenwoordig security scans voor repositories aanstaan. Er is dus veel meer beschikbaar, en ook die tools zijn het onderzoeken op toepasbaarheid waard.

Bronnen

Secure by Design: https://www.manning.com/books/secure-by-design

Securing DevOps: https://www.manning.com/books/securing-devops

Security by design – OWASP: https://wiki.owasp.org/index.php/Security_by_Design_Principles

Repository met code van dit artikel: https://github.com/mdeinum/securing-devops

Bio

Marten Deinum is een Software Engineer bij Conspect, daarnaast is hij auteur van 5 boeken gerelateerd aan Java en Spring. Hij deelt graag zijn kennis op het gebied van Java en Spring, daarnaast is hij in zijn vrije tijd duikinstructeur bij zijn eigen duikschool.