XSS sikkerhedshul i mange WordPress temaer og plugins

WordPress har en nyttig add_query_arg() funktion der kan bruges til at føje en query streng til en URL. F.eks:

// Append 'view=list' til 'http://h2g2.dk/oversigt'
$url = add_query_arg('view', 'list', 'http://h2g2.dk/oversigt');
// $url er nu 'http://h2g2.dk/oversigt/?view=list'

add_query_arg() sørger automatisk for at URL'en formateres korrekt når der er flere query variabler, f.eks:

$url = add_query_arg('display', 'recent', 'http://h2g2.dk/oversigt/?view=list');
// $url er nu 'http://h2g2.dk/oversigt/?view=list&display=recent'

Læg mærke til at add_query_arg() i eksemplet ovenfor bevarer det eksisterende ?view=list query, og at brugen af ? og & håndteres korrekt. Der findes en tilsvarende funktion remove_query_arg() som bruges til at fjerne en query variabel fra en URL.

Desværre har det indtil for nylig ikke fremgået af WordPress Codex at output fra disse funktioner ikke automatisk bliver escapet, dvs. renset for uønsket indhold. Dette er problematisk når man bruger add_query_arg() eller remove_query_arg() uden det sidste argument, dvs uden at angive en URL:

// URL på den kaldte side er 'http://h2g2.dk/oversigt/?view=list'
$uri = add_query_arg('display', 'recent');
// $uri er nu 'oversigt/?view=list&display=recent'

I dette tilfælde finder WordPress den streng som den nye query variabel skal føjes til ved hjælp af PHPs $_SERVER['REQUEST_URI] som indholder den kaldte URI (dvs. URL'en uden protokol og domænenavn). Men en angriber kan jo selv bestemme hvilken URL der kaldes og dermed også indholdet af $_SERVER['REQUEST_URI]. Hvis ikke indholdet af $_SERVER['REQUEST_URI] escapes inden det bliver brugt i WordPress så eventuelle kodestumper i den kaldte URL neutraliseres, er der åbnet mulighed for at gennemføre angreb blot ved at sende en specielt udformet URL til WordPress.

Udviklere kan forhindre at problemet opstår ved at escape output fra add_query_arg() og remove_query_arg()med esc_url() eller tilsvarende, men dette har mange åbenbart udeladt at gøre, måske fordi de antog at dette allerede var håndteret af WordPress. (En hurtig søgning fandt flere populære artikler der fejlagtigt påstår at input escaping er unødvendig med add_query_arg()/remove_query_arg(), f.eks. denne artikel fra tuts+).

Konsekvensen er at mange WordPress plugins og temaer indholder usikre kald til add_query_arg() og remove_query_arg() og disse er derfor i nogle tilfælde åbne for misbrug. Som altid er det derfor vigtigt at udviklere husker at escape bruger-genereret input, og at ejere af WordPress websites holder temaer og plugins opdateret løbende.