Pääsivu | Tiedotteet

WPML-haavoittuvuuksia

12.03.2015

Yleistä

WPML on johtava tekniikka monikielisen WordPress-sisällön hallintaan.

Liitännäisestä on löytynyt useita haavoittuvuuksia. Niistä vakavin, SQL injection, mahdollistaa kenelle tahansa WordPress-tietokannan sisällön lukemisen kokonaisuudessaan. Tietokanta sisältää mm. käyttäjien sähköpostiosoiteet ja salasanatiivisteet.

Ongelman voi korjata päivittämällä WPML-liitännäinen versioon 3.1.9.1, joka julkaistiin aiemmin tällä viikolla.

Yksityiskohdat

1. SQL injection

Kun WPML käsittelee HTTP POST -pyyntöä, joka sisältää parametrin "action=wp-link-ajax", liitännäisen käyttämä kielikoodi tulkataan HTTP referer -kentästä. Siitä saadun kielikoodin oikeellisuutta ei tarkisteta, eikä sitä "escapoida" SQL-hakuja varten. Virhettä hyödyntävän hyökkääjän ei tarvitse kirjautua sisään.

Lähettämällä sopivasti muotoillun referer-kentän mainitun POST-parametrin kanssa hyökkääjä voi suorittaa SQL-hakuja haluaamiinsa tauluihin ja vastaanottaa niiden tulokset. Normaalin WordPress-tietokannan ja taulujen lisäksi hyökkääjä voi lukea muidenkin sellaisten tietokantojen ja taulujen sisällön, joihin web-backendillä on pääsy.

Seuraava HTML-pätkä demonstroi haavoittuvuutta:


<script>
var union="select user_login,1,user_email,2,3,4,5,6,user_pass,7,8,9,10,11,12 from wp_users";
if (document.location.search.length < 2)
        document.location.search="lang=xx' UNION "+union+" -- -- ";
</script>

<form method=POST action="https://YOUR.WORDPRESS.BLOG/comments/feed">
<input type=hidden name=action value="wp-link-ajax">
<input type=submit>
</form>

SQL-haun tulokset näytetään kommentti-feedissä XML-muotoiltuna.

2. Sivujen/kirjoitusten/menujen poistaminen

WPML sisältää "menu sync" -toiminnon, joka auttaa sivuston ylläpitäjiä pitämään erikieliset WordPress-valikot keskenään konsistentteina. Toiminnallisuudesta puuttui pääsyvalvonta, joten haavoittuvassa versiossa kuka tahansa voi poistaa käytännössä kaiken sivuston sisällön - blogikirjoitukset, sivut ja valikot.

Esimerkki:


<form method=POST action="https://YOUR.WORDPRESS.BLOG/?page=sitepress-multilingual-cms/menu/menus-sync.php">
<input type=hidden name="action" value="icl_msync_confirm">
<input type=text name="sync" size=50 value="del[x][y][12345]=z">
<input type=submit>
</form>
Yllä olevan lomakkeen lähetys poistaisi wp_posts-taulusta rivin ID:llä 12345. Useita objekteja voi poistaa samalla HTTP-pyynnöllä.

3. Reflected XSS

Ylläpitäjille tarkoitettu "reminder popup" -toiminto ei tarkistanut kirjautumistilaa. Siihen liittyvä PHP-tiedosto sisältää XSS-virheen. Ohjaamalla käyttäjän seuraavalla tavalla muotoiltuun URLiin hyökkääjä voi suorittaa haluamaansa JavaScriptiä kohdekäyttäjän selaimessa WordPress-sivuston kontekstissa:

https://YOUR.WORDPRESS.BLOG/?icl_action=reminder_popup&target=javascript%3aalert%28%2fhello+world%2f%29%3b%2f%2f

Tämä esimerkki kiertää Chromen XSS Auditor -suojauksen.

WordPressin tapauksessa ylläpitäjään kohdistuva XSS-hyökkäys vaarantaa myös palvelinpuolen tietoturvan, koska vakioasetuksin JavaScriptillä voi kirjoittaa palvelimelle PHP-tiedostoja plugin- ja theme-editorien kautta.

4. Ylläpitotoiminnot ilman kirjautumista

Kirjautumaton käyttäjä voi kiertää WPML:n nonce-tarkistuksen ja suorittaa ylläpitotoimenpiteitä.

WPML suojaa ylläpidolliset ajax-toiminnot nonce-koodilla estääkseen asiattoman käytön. Mikäli nonce-tarkistus epäonnistui $_REQUEST-muuttujilla, WPML teki vielä toisen tarkistuksen ennen pyynnön eväämistä seuraavalla tavalla:


if (!( isset( $_GET[ 'icl_ajx_action' ] ) && $_GET[ 'nonce' ] == wp_create_nonce( $_GET[ 'icl_ajx_action' ] ) )) {
        die('Invalid nonce');
}

Ongelmaksi muodostuu $_REQUEST- ja $_GET-arvojen päällekkäinen käyttö. Jos yllä oleva tarkistus läpäistään, jatkossa koodi käyttää taas $_REQUEST-muuttujia suoritettavan ajax-toiminnon määrittämiseen.

Jos hyökkääjällä on hallussaan validi nonce-koodi, jonka kohteena olevan WordPress-sivuston jokin osa on generoinut, hän voi käyttää sitä yllä olevan tarkistuksen ohittamiseen ja suorittaa ylläpitotoimintoja kirjautumatta sisään.

Käytettävissä on tällöin n. 50 WPML:n toimintoa, jotka on tarkoitettu vain ylläpitäjien käyttöön. Ne tarjoavat monenlaisia mahdollisuuksia järjestelmän manipuloimiseen tai datan tuhoamiseen. Niiden avulla voi esimerkiksi määrittää html-tiedoston, joka evaluoidaan seuraavanlaisesti:


include $html_file;

Tämä mahdollistaa haluttujen tiedostojen lukemisen palvelimelta tai ulkopuolisilla verkkosivuilla olevan PHP-koodin suorittamisen (jos PHP:n asetukset sen sallivat).

WordPress ei ilmeisesti vakioasetuksin generoi nonce-koodeja sisään kirjautumattomille käyttäjille, joten ongelmaa ei luultavasti voi hyödyntää, ellei sivustolle ole asennettu muita liitännäisiä. Esimerkiksi Automatticin oma bbpress niitä kuitenkin generoi.

Esimerkki:


<form method=POST action="https://YOUR.WORDPRESS.BLOG/?icl_ajx_action=toggle-subscription_10&nonce=1234567890">
<input type=hidden name="icl_ajx_action" value="icl_save_language_negotiation_type">
<input type=hidden name="_icl_nonce" value="(ignored)">
<input type=hidden name="icl_language_negotiation_type" value="1">
<input type=hidden name="use_directory" value="1">
<input type=hidden name="show_on_root" value="html_file">
<input type=hidden name="root_html_file_path" value="/etc/passwd">
<input type=submit>
</form>

Tässä esimerkissä käytetään "toggle-subscription"-noncea, jonka bbpress generoi. Kirjautumaton käyttäjä voi hakea koodin kohdejärjestelmän keskustelusivuilta. Kun lomake lähetetään, WPML sallii ylläpitotoiminnon, koska bbpressin nonce-koodi on validi.

Suoritettava ajax-toiminto määritetään POST-parametreista. Tässä esimerkissä niillä muutetaan WPML:n asetuksia niin, että WordPressin oletussivuna näytetään palvelimelta tiedoston /etc/passwd sisältö.

Esimerkkikoodin toimivuus testattiin WPML:n versiolla 3.1.7.2.

5. Reflected XSS HTTP referer-kentän avulla

Ks. englanninkielinen versio.



Tekijä

Haavoittuvuudet löysi Klikki Oy:n Jouko Pynnönen osana Facebookin bug bounty -ohjelmaan liittyvien sivustojen tutkintaa.

Valmistajalle ilmoitettiin ongelmasta 02.03.2015 ja korjaus julkaistiin 10.03.