Overzicht

Penetration Test Report — Webapplicatie
[Klant]
Datum April/Mei 2026 Uitgevoerd door Fox&Fish — Johan Beysen Versie 1.0

Samenvatting

Tijdens deze tests werd de [APP]-webapplicatie onderzocht op kwetsbaarheden.

De autorisatielogica van de applicatie functioneert over het algemeen correct: gebruikers kunnen enkel data opvragen waartoe ze recht hebben, en tenant-isolatie werkt op de grote meerderheid van endpoints, op één uitzondering na: het genereren van rapporten.

De individuele bevindingen zijn overwegend van lage tot gemiddelde ernst. Een aantal van die kwetsbaarheden vormt samen echter uitvoerbare aanvalsketens. Twee van die ketens werden volledig uitgewerkt en gedemonstreerd:

  • Voorraadmanipulatie: een aanvaller met een geldig account kan via een gemanipuleerde link de voorraadcijfers van een slachtoffer aanpassen, zonder dat de beheerder of de gebruiker hiervan iets merkt. Eén klik volstaat.
  • Cross-tenant toegang tot productformules: via dezelfde techniek kan een aanvaller zich koppelen aan het account van een slachtoffer en vervolgens diens persoonlijke productformules uitlezen vanuit zijn eigen account.

Beide aanvallen verlopen volledig automatisch in de browser van het slachtoffer en zijn uitgevoerd in minder dan twee seconden. Het slachtoffer ziet enkel een korte foutmelding die vanzelf verdwijnt.

Hoewel de impact van deze ketens aanzienlijk is, kan de organisatie dit risico met relatief eenvoudige ingrepen wegnemen. De kern van het probleem ligt in een Reflected XSS-kwetsbaarheid in het endpoint Product.mvc/Detail en het ontbreken van CSRF-bescherming. Door het implementeren van een strikt Content Security Policy (CSP) en het afdwingen van anti-CSRF tokens op muterende acties, worden deze aanvalsvectoren effectief geblokkeerd zonder dat een ingrijpende herstructurering van de applicatie vereist is.

Risico-overzicht

Severity Aantal
CRITICAL 0
HIGH 4
MEDIUM 7
LOW 11
INFO 4

Scope

[APP] is een multitenant SaaS-platform van [KLANT] voor productbeheer, voorraadbeheer, jobregistratie en rapportage, gebruikt door productbeheerders en klantbedrijven wereldwijd.

De applicatie scheidt klantdata op data-niveau via een company-identifier; alle tenants delen dezelfde codebase en infrastructuur. Gebruikers kunnen expliciet aan meerdere companies gekoppeld worden via de “linked companies”-functionaliteit. Authenticatie verloopt via [IdP] ([IdP] SSO) over SAML.

Geteste omgevingen en hosts:

  • [APP]: [app.klant.com] (productie) en [qa.app.klant.com] (QA)
  • Authenticatieportalen: [auth.klant.com] en [qaauth.klant.com]
  • Aanverwante hosts: [stage.klant.com] en [data.klant.com]

De focus lag op de multitenant architectuur en op functionaliteit met directe business-impact: productbeheer, voorraadbeheer, rapportage en account linking.

Probleemstelling

De vraag die voorafging aan dit onderzoek was tweeledig:

Zijn de grenzen tussen tenants scherp genoeg — en kan een aanvaller, al dan niet met een geldig account, data inzien of manipuleren die hem niet toekomt?

De architectuur houdt klantdata gescheiden via een company-identifier, maar elke scheiding is zo sterk als de zwakste plek in de implementatie. Meer concreet leefden er vóór de testen de volgende vragen:

  • Kan een geauthenticeerde gebruiker data van een andere tenant bereiken?
  • Zijn state-changing acties — het aanpassen van voorraad, het opslaan van formules, het koppelen van accounts — beveiligd tegen misbruik vanuit een externe context?
  • Welke informatie lekt de applicatie onbedoeld, en wat geeft een aanvaller een voorsprong bij een gerichte aanval?
  • Is de authenticatielaag ([IdP] via SAML) correct geconfigureerd, of zijn er aanknopingspunten op het niveau van de identity provider?

Top 3 bevindingen

  1. Cross-Site Scripting (XSS) — Reflected & Stored: De applicatie voert zonder sanitisatie gebruikersinput terug uit als JavaScript in de browser van andere gebruikers. Via een gemanipuleerde URL of een opgeslagen formula kan een aanvaller willekeurige JavaScript uitvoeren in de sessie van een slachtoffer en zo namens die gebruiker acties stellen of data uitlezen.

  2. Cross-Site Request Forgery (CSRF) — Geen tokenbescherming: Geen enkel state-changing endpoint valideert een anti-CSRF-token. Hiermee kunnen gebruikers gemanipuleerd worden om ongewild en ongemerkt acties uit te voeren op hun tenant: voorraadwijzigingen, het koppelen van een vreemd bedrijf aan hun account, of het opslaan van formules.

  3. Cross-tenant rapporttoegang — IDOR op Reporting-endpoints: De rapport-generatie-endpoints accepteren een client-supplied company ID zonder server-side autorisatiecheck. Een geauthenticeerde gebruiker met de identifier van een andere tenant kan rapporten genereren op data van die tenant — stockgegevens, prijsinformatie en bedrijfsdata inbegrepen.

Conclusie en belangrijkste adviezen

Twee concrete aanvalsketens zijn volledig uitgewerkt en gedemonstreerd; beide zijn te doorbreken met gerichte fixes in de applicatielaag.

De prioriteit ligt bij het oplossen van de Reflected XSS en het toevoegen van CSRF-tokens op schrijfacties. Dat doorbreekt beide aanvalsketens in één beweging. De overige bevindingen zijn minder urgent maar verdienen opvolging als onderdeel van een bredere verstevigingsronde — ze verlagen de drempel voor toekomstige aanvallen en lekken informatie die een aanvaller een voorsprong geeft.

De drie kernmaatregelen:

  1. Input sanitisatie & output encoding — Valideer gebruikersinput op elk inputveld en pas context-bewuste output encoding toe bij het terugplaatsen in HTML- of JavaScript-context. Verwijder unsafe-inline en unsafe-eval uit de Content Security Policy en migreer naar een nonce-gebaseerde aanpak.

  2. Anti-CSRF tokens — Implementeer [ValidateAntiForgeryToken] op alle state-changing endpoints. Configureer dit als globaal filter zodat nieuwe endpoints automatisch beschermd zijn. Dwing af dat state-wijzigende acties uitsluitend via POST aanroepbaar zijn.

  3. Server-side autorisatie — Valideer op elke controller-action of de geauthenticeerde gebruiker toegang heeft tot de opgevraagde resource, ongeacht welke identifier de client meestuurd. Verberg-in-menu is geen autorisatielaag.