# REST-API's in PHP beveiligen

> REST-API's in PHP beveiligen: authenticatie, controle per object, JWT, grootte- en typegrenzen, foutmeldingen en snelheidsbeperking met voorbeeldcode.

Bron: https://phpsos.de/nl/blog/rest-api-php-absichern/  
Stand: 25-10-2026  
Aanbieder: PHP SOS, PHP-noodhulp en serverbeveiliging. Directe hulp via WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wij%20hebben%20hulp%20nodig%20met%20onze%20PHP-server.%20Bedrijf%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort gezegd:** Voor de API-beveiliging in PHP tellen vooral vijf punten: alleen HTTPS, authenticatie bij elk niet-openbaar eindpunt, machtigingscontrole voor elk afzonderlijk object, strikte grenzen voor methode, inhoudstype en grootte van het verzoek en beknopte foutmeldingen zonder interne details. Daarbij komen snelheidsbeperking en een logboek van beveiligingsrelevante gebeurtenissen. Tegen kwetsbaarheden in de PHP-interpreter zelf zoals PHP2Shell helpt dat niet; daarvoor is de PHP-update nodig.

## De interface achter de website

Veel bedrijven hebben in de week na 21-10-2026 hun websites gecontroleerd. De interfaces erachter stonden minder vaak op de lijst. Toch lopen juist daar gevoelige processen: de app van het klantenportaal haalt facturen op, het ERP-systeem schrijft voorraden naar de webshop, een partner meldt orders via een webhook. Vaak werden deze API's snel gebouwd, voor één enkel doel, en daarna nooit meer bekeken.

Een API heeft geen oppervlak dat fouten zichtbaar maakt. Een ontbrekende machtigingscontrole valt in het dagelijks gebruik niemand op, zolang alle clients alleen opvragen wat ze mogen. Een aanvaller probeert daarentegen precies wat niet is voorzien.

De eerste stap is daarom een inventarisatie. Welke eindpunten bestaan er überhaupt? Vaak zijn er oude versies zoals `/api/v1/`, die na de overstap naar `/v2/` nooit zijn uitgeschakeld, testeindpunten uit de ontwikkeling of een openbaar op te halen interfacebeschrijving die interne functies opsomt. Elk eindpunt dat niet meer nodig is, moet worden uitgeschakeld. Elk eindpunt dat blijft, heeft een verantwoordelijke nodig.

## API-beveiliging in PHP: de basisregels

De OWASP REST Security Cheat Sheet vat beproefde regels samen. Voor PHP-projecten zijn ze te vertalen in een korte lijst:

1. **Alleen HTTPS.** Tokens en toegangsgegevens mogen nooit onversleuteld worden verzonden.
2. **Elk eindpunt controleert zelf.** De authenticatie kan centraal plaatsvinden, de beslissing over de toegang valt bij het eindpunt.
3. **Machtiging per object.** Niet alleen "is aangemeld", maar "mag precies dit gegevensrecord".
4. **Toegestane methoden vastleggen.** Wat niet uitdrukkelijk is toegestaan, wordt met 405 afgewezen.
5. **Inhoudstype en grootte controleren.** Verkeerd type levert 415, te grote verzoeken 413.
6. **Invoer valideren.** Type, lengte, formaat en waardenbereik, aan de serverkant.
7. **Geen geheimen in URL's.** Tokens en sleutels horen in headers, niet in de querystring.
8. **Beknopte fouten.** Geen stacktraces, paden of SQL-meldingen naar de client.
9. **Snelheidsbeperking.** Te veel verzoeken worden met 429 beantwoord.
10. **Beheereindpunten afschermen.** Niet openbaar bereikbaar of alleen met sterke aanmelding.

## Objectmachtiging: de meest voorkomende fout

Een voorbeeld maakt het probleem tastbaar. Een eindpunt levert facturen onder `/api/rechnungen/{id}`. Gecontroleerd wordt of er een geldig token is. Niet gecontroleerd wordt of de factuur bij de klant van het token hoort. Wie zijn eigen factuurnummer met één ophoogt, ziet die van de buurman.

De oplossing is eenvoudig en moet toch op elke plek worden doorgevoerd: de query zelf beperkt tot het gemachtigde bereik.

```php
<?php
// Alleen methode GET toestaan
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
    http_response_code(405);
    header('Allow: GET');
    exit;
}

$kundeId = $auth->kundeId();          // uit het gecontroleerde token
$id = filter_var($routeId, FILTER_VALIDATE_INT);
if ($id === false) {
    http_response_code(400);
    exit;
}

// Machtiging zit in de query: alleen eigen facturen
$stmt = $pdo->prepare('SELECT nummer, betrag, datum FROM rechnungen WHERE id = ? AND kunde_id = ?');
$stmt->execute([$id, $kundeId]);
$rechnung = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$rechnung) {
    http_response_code(404);           // niet verraden of de ID bestaat
    exit;
}

header('Content-Type: application/json');
echo json_encode($rechnung, JSON_THROW_ON_ERROR);
```

De query met plaatshouders beschermt tegelijk tegen SQL-injectie, zie [SQL-injectie in PHP voorkomen](https://phpsos.de/nl/ratgeber/sql-injection-php/). Hoe PHP verzoekgegevens zoals methode, headers en body beschikbaar stelt, legt [Superglobals: $_GET, $_POST, $_FILES en meer](https://phpsos.de/nl/php/superglobals/) uit.

## Tokens correct controleren

Veel API's werken met JSON Web Tokens. De OWASP Cheat Sheet noemt daarvoor duidelijke regels: tokens moeten zijn ondertekend, niet-ondertekende tokens worden afgewezen en het algoritme voor de controle wordt op de server vastgelegd, niet uit het token overgenomen. Uitgever, doelgroep en vervaltijd horen ook bij de controle. Gebruik daarvoor een onderhouden bibliotheek in plaats van eigen implementaties.

Eigen tokens, bijvoorbeeld voor webhooks of eenmalige links, moeten uit een cryptografisch veilige generator voor willekeur komen en in constante tijd worden vergeleken. Hoe dat in PHP gaat, toont [Veilige willekeurige getallen en tokens in PHP](https://phpsos.de/nl/blog/sichere-tokens-php/).

> **Tip:**
> Geef elke client en elke partner een eigen sleutel met precies de rechten die hij nodig heeft. Dan is een weggelekte sleutel afzonderlijk te blokkeren, zonder alle andere koppelingen te onderbreken.

## Grenzen stellen: grootte, type en tempo

Een API moet alleen aannemen wat ze verwacht. Dat begint bij het inhoudstype: een eindpunt dat JSON verwerkt, wijst al het andere af. De maximale grootte van een verzoek beperkt u op meerdere niveaus, in de webserver en in PHP via `post_max_size`. Deze grens hoort ook bij de overgangsmaatregelen die php.net over PHP2Shell heeft genoemd. Hoe men haar zinvol kiest, beschrijft [post_max_size en upload_max_filesize zinvol beperken](https://phpsos.de/nl/blog/post-max-size-upload-limits/).

Snelheidsbeperking beschermt tegen het doorproberen van aanduidingen en tegen overbelasting. Ze is door te voeren in de webserver, in een voorgeschakelde proxy of in de applicatie. Belangrijk is dat grenzen per sleutel of gebruiker gelden en niet alleen per IP-adres.

Voor API's die rechtstreeks vanuit de browser worden aangeroepen, komt CORS erbij, dus de regels welke vreemde websites verzoeken mogen doen. Stel deze headers alleen in als zulke aanroepen werkelijk zijn voorzien en noem de toegestane herkomsten afzonderlijk, in plaats van elke herkomst toe te laten. Een jokerteken dat alle websites toestaat, is bij eindpunten met aanmelding bijna altijd een fout.

Tot slot het logboek: mislukte aanmeldingen, afgewezen tokens en geweigerde toegang horen in het log, tokens zelf niet. Zonder deze vermeldingen blijft een aanval op de API onzichtbaar.

## Hoe helpt PHP SOS concreet?

- Wij inventariseren alle interfaces van uw PHP-systemen, ook vergeten en interne, en controleren welke openbaar bereikbaar zijn.
- Wij lezen de machtigingslogica en testen gericht of vreemde gegevensrecords op te halen zijn.
- Wij stellen grenzen voor grootte, type en tempo in webserver en PHP in en stemmen ze af met uw clients.
- Voor een uitgebreide controle van buitenaf combineren wij dit met [beveiligingsaudit en penetratietest](https://phpsos.de/nl/leistungen/sicherheitsaudit-penetrationstest/).

**Conclusie:** Een API is zo veilig als haar slordigste eindpunt. Wie machtigingen per object controleert, duidelijke grenzen stelt en fouten beknopt houdt, dicht de meest voorkomende kwetsbaarheden lang voordat iemand er gericht naar zoekt.


## Veelgestelde vragen

**Is een API-sleutel genoeg als bescherming?**  
Voor gevoelige gegevens niet. Een API-sleutel identificeert meestal een applicatie, geen gebruiker, en wordt gemakkelijk doorgegeven. De OWASP REST Security Cheat Sheet adviseert API-sleutels niet als enige bescherming voor gevoelige bronnen te gebruiken.

**Wat is een objectmachtiging en waarom ontbreekt ze zo vaak?**  
Bedoeld is de controle of de aangemelde gebruiker precies dit gegevensrecord mag zien of wijzigen. Ze ontbreekt vaak, omdat ontwikkelaars alleen controleren of er überhaupt iemand is aangemeld. Dan volstaat het een aanduiding in de URL te wijzigen om vreemde gegevens op te halen.

**Beschermt een goed beveiligde API tegen PHP2Shell?**  
Nee. PHP2Shell zit in de PHP-interpreter en werkt bij getroffen bedrijfsmodi voordat uw code überhaupt draait. Daartegen helpt alleen een PHP-update met herstart. Groottegrenzen voor verzoeken zijn toch zinvol en horen ook bij de overgangsmaatregelen van php.net.

**Welke statuscodes moet een API bij beveiligingsfouten leveren?**  
Gebruikelijk zijn 401 zonder geldige aanmelding, 403 bij ontbrekende machtiging, 405 bij niet-toegestane methode, 413 bij een te groot verzoek, 415 bij een verkeerd inhoudstype en 429 bij te veel verzoeken. Het antwoord zelf blijft daarbij beknopt en zonder interne details.

## Bronnen

- [OWASP: REST Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [PHP-handleiding](https://www.php.net/manual/de/)
- [php.net: beveiligingsmeldingen](https://www.php.net/)
