Lesmateriaal Webapplicatie Beveiliging – NGINX & Apache

Voorwoord

In deze blogpost zal ik verschillende methodes van het uitbuiten van beveiligingslekken beschrijven. Dit is in geen enkele mate toestemming om deze injecties, uitbuitingen en hacks uit te voeren en dient enkel als voorbeeld om het idee van beveiliging te onderbouwen. Om deze reden ga ik niet heel diep in op de hacking onderdelen en meer in op het idee van beveiliging. Deze blogpost is de eerste van een vier-delige reeks aan blogposts over de beveiliging van webapplicaties, vanuit het oog van een docent. Veel leesplezier!

Inleiding

Wanneer je een website wilt hosten op een server moet je een webserver opzetten. Deze webserver toont een website op het IP-adres van de server. In dit dossier wil ik twee van de meest gebruikte webservers behandelen: Apache en NGINX. Het grootste verschil mijn mening is dat Apache het configuratiebestand tussen de webbestanden heeft staan, waar NGINX het configuratiebestand op een eigen plek heeft staan (zonder het meerekenen van includes e.d.). Apache kan meerdere van deze configuratie bestanden per map van een website hebben, zodat de toegang per map specifiek kan worden ingesteld. NGINX regelt dit via 1 bestand waar de instellingen via paths moeten worden ingesteld.

Apache

Het configuratiebestand van Apache heet .htaccess. Dit verborgen bestand staat standaard in de root (de hoofdmap) van de website en bepaald de instellingen van de website. Zoals hierboven beschreven kunnen de submappen ook hun eigen .htaccess bestand bevatten, zodat er specifieke instellingen kunnen worden geschreven per map. Een .htaccess bestand kan er bijvoorbeeld zo uitzien:

ErrorDocument 400 /400.html
ErrorDocument 401 /401.html
ErrorDocument 403 /403.html
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
ErrorDocument 502 /502.html
ErrorDocument 504 /504.html

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.website.nl [NC]
RewriteRule ^(.*)$ http://website.nl/$1 [L,R=301]
In weze is het een bestand vol met configuraties, waar ik in dit voorbeeld twee veel gebruikte onderdelen heb gebruikt. In het eerste blok heb ik de ErrorDocuments toegewezen. Dit zijn de webpagina’s die worden getoond wanneer de gebruiker tegen een specifieke HTTP-status code aanloopt. Deze codes worden in verschillende situaties getoond. De meest bekende 404 code wordt weergeven wanneer een pagina niet gevonden is. Via de code:

ErrorDocument 404 /404.html
Kun je een eigen gemaakte pagina tonen die bijvoorbeeld de gewenste huisstijl heeft, in plaats van de standaard foutmeldingspagina. In het tweede blok heb ik een Rewrite geplaatst. Deze Rewrite herschrijft in wezen de URL naar wens. In dit geval zorg ik ervoor dat een gebruiker geen “www.” voor de domeinnaam hoeft te zetten.

NGINX

Bij NGINX ziet het configuratiebestand er iets anders (misschien ietwat ingewikkelder) uit. NGINX gebruikt vaak ook meerdere configuratiebestanden, waar het hoofdbestand alle globale instellingen bevat en per website een apart configuratiebestand kan worden gemaakt. Deze bestanden staat vaak op een andere locatie dan de webroot (bijvoorbeeld /etc/nginx). Daarom moeten we de webroot ook zelf aangeven in het bestand. Ik zal hier een voorbeeld plaatsen van een generiek NGINX bestand die specifiek is gericht op een website, waarna ik het bestand zal uitleggen.

server {
	server_name	website.nl www.website.nl;
	
	root			/var/www/website.nl;

	error_page 400	/var/www/400.html;
	error_page 401	/var/www/401.html;
	error_page 403	/var/www/403.html;
	error_page 404	/var/www/404.html;
	error_page 500	/var/www/500.html;
	error_page 502	/var/www/502.html;
	error_page 504	/var/www/504.html;
}
Het bovenstaande bestand is onderdeel van het algemene configuratiebestand en beschrijft de instellingen die specifiek voor het domein “website.nl” zijn. Eerst wordt het server object geopend met server en worden de configuraties omringt door accolades. Als eerste wordt de domeinnaam ingesteld onder server_name. In dit geval worden zowel de www als de non-www variant naar dezelfde webroot gestuurd. Daarna wordt de webroot, de plek waar de bestanden van de website staan, ingesteld. Als laatste heb ik, om de configuraties van het bovenstaande .htaccess bestand hetzelfde te houden, de HTTP-status code pagina’s ingesteld.

Beveiliging

Apache

httpd.conf

Apache zelf als proces heeft ook een configuratiebestand. Waar het .htaccess bestand in de webroot (of in submappen) de configuraties vormt voor de specifieke website, bevat het httpd.conf bestand de configuraties voor de Apache server in het algemeen. Dit bestand bevat behoorlijk wat instellingen die allemaal uitgelegd staan in de documentatie, maar een aantal wil ik hiervan benoemen als voorbeeld hoe beveiliging kan worden toegepast middels het httpd.conf bestand. Apache heeft standaard een redirect aan staan die de gebruiker naar een pagina leidt waar veel server informatie staat. Net zoals bij het PHP voorbeeld, waar phpinfo() niet moet worden gebruikt op productie omgevingen, is dit informatie waarvan het niet gewenst is dat een gebruiker het ziet. Dit kan worden uitgeschakeld door de volgende regels uit te zetten in het configuratiebestand, door er hashtags (#) voor te zetten:

#
# SetHandler server-status
# Order deny,allow
# Deny from all
# Allow from .your_domain.com
#
Een zelfde voorbeeld hiervan is de ServerSignature functionaliteit, die een soort handtekening (ofwel een “Footer”) plaatst onder server-gegenereerde documenten. In deze Footer staat informatie over de Apache configuratie zoals de versie en het besturingssysteem waar de webserver op draait. Dit kan worden uitgeschakeld door de ServerSignature configuratie in het bestand een waarde van Off te geven:

ServerSignature Off

Modules

Apache bevat modules, wat eigenlijk modulaire functionaliteiten zijn. Het voordeel aan het feit dat deze functionaliteiten modulair zijn, is dat de functionaliteiten afzonderlijk van elkaar kunnen draaien. Dat betekent dat functionaliteiten die niet worden gebruikt het beste kunnen worden uitgeschakeld. Meer functionaliteiten betekent meer potentiële kwetsbaarheden en deze wil je zoveel mogelijk indammen. Een uitgebreide documentatie van de Apache modules is hier te vinden. Modules kunnen worden uitgeschakeld door de bijbehorende LoadModule regels te commenten met een hashtag:

#LoadModule status_module "modules/mod_status.so"

Toegang

Via het .htaccess bestand kan je bepalen wie welke bestanden of mappen mag inzien. Een heel concreet voorbeeld hiervan is het blokkeren van een specifieke map voor alle gebruikers, behalve specifieke IP adressen (bijvoorbeeld voor testen):

Deny from All
Allow from 39.163.68.68
Deny from All blokkeert de map waar het .htaccess bestand in staat voor iedereen. Vervolgens staat de regel Allow from IP-ADRES een specifiek IP adres toe. Deze gebruiker heeft wel toegang tot deze map. Een meer praktisch voorbeeld is het blokkeren van verborgen bestanden en mappen voor gebruikers. Vrijwel in geen enkel geval is het wenselijk dat een gebruiker toegang heeft tot een verborgen bestand of map (een bestand of map dat begint met een punt (.)). Via Rewrites kan dit worden bereikt:

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]
RedirectMatch 404 /\..*$
Dit stuk configuratie maakt gebruikt van een reguliere expressie (een soort patroon dat kijkt of data in het patroon valt) om te kijken of het bestand of de map waar de gebruiker toegang tot vraagt een verborgen bestand of map is. Als dat zo is, dan wordt de gebruiker doorgestuurd naar een 404 pagina. Het voordeel hieraan is, is dat jij de gebruiker op deze manier het idee geeft dat de pagina niet bestaat, in plaats van dat jij de gebruiker bekend maak dat het bestand of de map verborgen is. Je wilt de gebruiker bijna nooit informatie geven over de processen die onder water lopen. Een ander praktisch voorbeeld van toegangsbeveiliging is bijvoorbeeld de gebruiker toegang weigeren tot bestanden met een specifieke extensie. In dit voorbeeld weigeren we gebruikers die toegang willen tot de volgende bestandsextensies:

.bak, .config, .ini, .log, .sql
Dit doen we als volgt:


    Order allow,deny
    Deny from all
    Satisfy All

Directory Browsing

Als laatste wil ik nog kort de functionaliteit Directory Browsing benoemen. Wanneer ik als gebruiker een map in plaats van een bestand benader, geeft Apache de optie om deze map te tonen en de onderliggende bestanden en mappen te tonen als links naar deze bestanden en mappen. Dit is misschien handig tijdens het ontwikkelen van een website, maar een groot beveiligingsrisico op productie omgevingen. Het is daarom aangeraden dit meteen uit te schakelen op een productie omgeving. Dit kan gelukkig met 1 enkele regel worden uitgevoerd:

Options All -Indexes

NGINX

nginx.conf

Waar Apache een algemeen configuratiebestand genaamd httpd.conf heeft, heet het algemene configuratiebestand van NGINX nginx.conf. In dit bestand zijn er ook een aantal settings die omwille van beveiliging kunnen worden ingesteld. Een goed voorbeeld hiervan is de instelling server_tokens, die de huidige NGINX versie toont aan gebruikers. Dit is informatie die de gebruiker niet hoeft te zien en eventueel aan gebruikers met kwade bedoelingen toont of er een out-of-date versie is waar potentiële beveiligingslekken in kunnen zitten. Deze configuratie kan als volgt worden uitgeschakeld, door de waarde off te geven:

server_tokens off;
De groottes van buffers voor proxy servers (voor wanneer een gebruiker wacht op een response (antwoord) van een proxy server) kan worden gebruikt voor kwade bedoelingen in een zogenaamde Buffer Overflow Attack. Buffer groottes kunnen met de volgende instellingen worden ingesteld:

	client_body_buffer_size 128k;
	client_max_body_size 10m;
	client_header_buffer_size 1k;
	large_client_header_buffers 4 4k;
Voor NGINX is er een module die betere beveiliging instelt en in wezen dient als een firewall voor de web applicatie. Daarom is het aangeraden de ModSecurity module te installeren. Er zijn veel bronnen voor het installeren van deze module, waaronder de handleiding op NGINX.com<>/a> zelf.

Modules

NGINX kent dezelfde modulaire functionaliteiten als we hebben gezien bij Apache. Ook hier is het belangrijk om modules uit te schakelen die niet worden gebruikt. Bijvoorbeeld, als we de geoIP module willen uitschakelen, kunnen we dat doen in het bestand dynamic-modules.conf, door de volgende lijn te commenten met een hashtag:

#load_module "modules/ngx_http_geoip_module.so";

Toegang

Ook in NGINX is het ten zeerste aan te raden aandacht te besteden aan de toegangsrechten van gebruikers. Hierbij hetzelfde voorbeeld als bij Apache, het blokkeren van verborgen bestanden en mappen voor gebruikers:

location ~ /\. {
    deny all;
}
Als we de specifieke bestandsextensies die beschreven staan bij het “toegang” kopje bij de Apache beveiliging, dan zullen we het volgende moeten schrijven:

location ~\.(bak|config|ini|log|sql)$ {
    deny all;
    error_page 403 =404 / ;
}

Lesvoorbereidingsformulier

Lijkt je het leuk om hier een les in geven maar heb je geen idee hoe je moet beginnen? Dan kun je altijd dit lesvoorbereidingsformulier gebruiken die is gemaakt voor 1e jaars studenten van de MBO opleiding Software Development. Al het geschreven materiaal is Open-Source en vrij om te gebruiken.
Lesvoorbereidingsformulier