Security by design: kwetsbaarheden van de browser

Geschreven door Rob Dekkers

In de vorige blogs hebben we specifiek gekeken naar kwetsbaarheden in een Mendix app en maatregelen om risico op misbruik te verminderen of te vermijden. In deze blog zullen we enkele belangrijke kwetsbaarheden van browsers en oplossingen hiervoor bespreken. Deze kwetsbaarheden gelden niet alleen voor Mendix apps, maar voor alle webapplicaties. De stichting OWASP (Open Web Application Security Project) heeft hier uitgebreide informatie over (owasp.org). Zij publiceren de OWASP top 10 van meest gemaakte fouten en bieden kennis en tools om kwetsbaarheden te onderkennen.

Injectie en Cross-site scripting

Injectie staat in de OWASP-lijst van 2021 op nummer 3 (in 2017 op nummer 1). Dit is inclusief cross-site scripting, omdat dat een specifieke vorm van injectie is. Bij injectie heeft de gebruiker de mogelijkheid om programmacode in de user interface als data in te voeren die vervolgens op de server (bijv. SQL-injectie) of client (bijv. Javascript-injectie) wordt uitgevoerd.

SQL- of OQL-injectie is niet direct een kwetsbaarheid van de browser, maar meer van de applicatie. Bij standaard Mendix apps is dat niet mogelijk, omdat er standaard geen SQL/OQL-code wordt geprogrammeerd. Er wordt gebruik gemaakt van Retrieve/Change/Delete actions waarvan de code vastligt en de stringparameters worden voorzien van quotes (onderwater), zodat input niet als code kan worden geïnterpreteerd.

Alleen als een SQL/OQL-statement als tekststring wordt opgebouwd in een Java action, zou injectie mogelijk zijn. Een klassiek voorbeeld is:

userid = request.getParameter('UserId');
sql = 'select * from users where userid = ' + userid;

data input voor UserId: 100 or 1=1

Bij Javascript-injectie wordt Javascriptcode als invoer gegeven, bijvoorbeeld:

<script>alert('Deze alert is ingevoerd als data.');</script>

Indien deze data als HTML in een webpagina wordt opgenomen, dan wordt het als code in de browser uitgevoerd.

Javascript-injectie is in standaard Mendix-apps niet mogelijk, omdat de Mendix runtime de data tussen server en client voorziet van escape karakters (bijv. < wordt &lt;), indien gebruik gemaakt wordt van de standaard widgets. De marketplace module CommunityCommons heeft hier ook nog functies voor: EscapeHTML en HTMLEncode.

Echter kunnen sommige widgets ruwe HTML presenteren, zoals Dynamic Label (als eigenschap Render XHTML true is), HTML viewer en FormatString. Het is dan wel degelijk mogelijk dat de data als code wordt uitgevoerd. Hier moet worden voorkomen door validatie van input dat invoerdata die op deze wijze wordt getoond geen uitvoerbare Javascriptcode bevat. OWASP biedt hiervoor een Java library AntiSamy die als onderdeel van CommunityCommons beschikbaar is in de functie XSSSanitize. Met AntiSamy is het mogelijk met regels te definiëren wat wel en niet gezuiverd moet worden. Advies is altijd om deze zo strict mogelijk in te stellen, tenzij dat om functionele redenen niet mogelijk is.

Browserfaciliteiten tegen Cross-site scripting

De moderne browsers bieden faciliteiten die beschermen tegen cross-site scripting. Hoewel niet helemaal kan worden voorkomen, kan het wel moeilijker worden gemaakt en kunnen de gevolgen worden ingeperkt.

Een hulpmiddel om de schade van een script te beperken is de Content Security Policy (CSP). Hiermee kan via een http header worden aangegeven waar toegang tot resources is toegestaan. Bijvoorbeeld is een strikte definitie als volgt:

Content-Security-Policy: default-src 'self';

Deze regel geeft aan dat content alleen vanaf dezelfde locatie mag worden benaderd als waar de pagina oorspronkelijk vandaan kwam en dat inline scripts en styles niet toegestaan zijn. Het is trouwens best practice om geen inline scripts en styles te gebruiken, maar altijd te verwijzen naar externe bestanden hiervoor. CSP heeft veel instelmogelijkheden om flexibel aan te geven wat niet of wel mogelijk is.

Eén van de parameters van CSP is frame-ancestors, waarmee het mogelijk is om te voorkomen dat de HTML-pagina in een frame wordt getoond (‘none’) of alleen een frame vanaf dezelfde locatie (‘self’). Dit kan zogenaamde clickjacking attacks voorkomen. Bij een clickjacking attack wordt een muisklik in het frame door de pagina die het frame bevat afgevangen om er iets anders mee te doen. Een oudere optie voor het voorkomen van frames is de http header X-Frame_Options (DENY, SAMEORIGIN) die in oudere browsers wordt ondersteund.

Indien in Javacode cookies worden geplaatst, dan zijn er een aantal instellingen van belang in dit kader:

  • Expiration time
    Indien geen expiration time is ingesteld, dan betreft het een session cookie die bij het afsluiten van de browser worden opgeruimd.
  • HttpOnly
    Voorkom dat Javascriptcode het cookie kan inzien.
  • SameSite
    Voorkom dat het cookie meegestuurd wordt naar andere websites. Waarden zijn Lax (default in moderne browsers) en Strict.

Indien de inhoud van een cookie in de applicatie wordt gebruikt, dan moet ervan uitgegaan worden dat een kwaadwillende gebruiker de inhoud kan hebben aangepast.

Als laatste noemen we de beperking die aan Javascriptcode door de browser per default wordt opgelegd, de zogenaamde same-origin policy. Javascriptcode kan dan alleen interactie hebben met resources of services van dezelfde website. Indien dit te strikt zou zijn, bijvoorbeeld als in een AJAX-call een service van een andere website wordt aangeroepen, dan is hiervoor het mechanisme Cross-Origin Resource Sharing (CORS) gedefinieerd. CORS staat toe om aan te geven welke andere resources (URLs) te benaderen zijn en met welke HTTP methoden. De implementatie bestaat uit het uitwisselen tussen browser en webserver van http headers waarin wordt aangegeven wat toegestaan is. Soms impliceert dit dat er twee requests nodig zijn om te bepalen wat toegestaan is (preflight).

Mendix hardening

In de Mendix portal zijn een aantal mogelijkheden om de risico’s op schade door browserkwetsbaarheden te verkleinen.

In de Environment van een applicatie is het mogelijk om HTTP Headers te definiëren, zodat ze aan alle pagina’s worden toegevoegd. De CSP, CORS en diverse andere headers zijn daar toe te voegen. Vanaf Mendix 8 kan ook de SameSite eigenschap van cookies worden ingesteld.

Tevens kunnen paden (delen van de URL) binnen de applicatie worden beveiligd door de toegang ertoe te beperken. Het is mogelijk volledig te blokkeren of een controle op een client certificaat of IP-reeks uit te voeren.

In de volgende en laatste blog uit deze serie zullen we ingaan op het uitvoeren van pentesten op Mendix apps.