WordPressi haakimiskohad ehk konksud ja filtrid

Haak või kõrvalepõige on nagu nõudepeatus või küsimus “kas astun töölt koju tulles poest läbi?” ehk kellegi poolt kirjutatud koodi on taotluslikult jäetud võimalus selle kulgu mõjutada.

WordPressis on kahte sorti haakimiskohti:

  • hook e. konks on nagu nagi, kuhu igaüks saab riputada oma täitmist vajavad funktsioonid;
  • filter võimaldab huvilistel andmeid mudida, reeglina enne väljastamist.

Konksudest ja filtritest räägib kolmapäeval, 09.10.2019 kell 19 algaval WordPressi meetupil ka Arūnas Liuiza.
Tule kohale kuulama ja küsima!

Konks

Selle illustreerimiseks sobib alamteemade postituses olev näide, kus lisasin Google Analytics’i header.php koodi:

Kuna header.php sai kopeeritud alamteema kataloogi tuleb sellise laiendamise puhul arvestada, et kui põhiteemas see fail uueneb on vaja neid a) märgata b) käsitsi alamteemasse üle tuua.

Jätkusuutlikum lahendus on päise konks:

<?php wp_head(); ?>

See teeb täpselt ühte asja – kutsub välja kõik ennast wp_head konksu külge haakinud funktsioonid:

function wp_head() {
/**
* Prints scripts or data in the head tag on the front end.
*
* @since 1.5.0
*/
	do_action( 'wp_head' );
}

Praktikas haagivad ennast sinna kõik skriptid-CSSid-metaväljad jne (seejuures mõned nt JS ja CSS kasutades  spetsiaalseid konkse, mis ennast wp_head külge haagivad).

Sama analüütika-koodi saaksime lisada alamteema functions.php faili nii:

function petskratt_analytics() {
?>
	<!-- Global site tag (gtag.js) - Google Analytics -->
	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxx-1"></script>
	<script>
	  window.dataLayer = window.dataLayer || [];
	  function gtag(){dataLayer.push(arguments);}
	  gtag('js', new Date());
	
	  gtag('config', 'UA-xxxxxx-1');
	</script>
<?php
}

add_action('wp_head', 'petskratt_analytics', 1);

Kirjeldan funktsiooni ning haagin ta nime pidi add_action abil sobilikku kohta, viimane parameeter on prioriteet ehk vastavalt Google Analytics’i soovitusele tahaks nende jupp olla võimalikult <head> alguses. Päris esimeseks ei saa, aga need eelnevad meta-väljad ei ole ka kuidagi probleemiks.a

Nüüd võin ka Twenty Nineteen’i julgesti uuendada, minu alamteema muudab põhiteema ja WordPressi käitumist vastavalt parimale tavale.

Selliseid konkse on WordPressis umbes 800 – ja lisaks 1700 filtrit.

Filter

Konks on abiks, kui tahad ise midagi väljastada – aga mida teha juhul, kui tahaksid muuta mõne teise funktsiooni poolt väljastatavat? Näiteks prooviks postituse sisu kuvada AINULT SUURTÄHTEDEGA … või veel parem (jaburam) SuvaLIsE SuuRUsEGA.

Tegevuste ahel on selline:

  1. teema kutsub sobilikus kohas välja funktsiooni the_content()
  2. the_content() leiab andmebaasist postituse sisu, valmistab selle kuvamiseks ette… aga enne kuvamist pakub võimalust the_content filtri külge haakinud funktsioonidele seda muuta
  3. sinu funktsioon haagib ennast the_content filtri külge, teeb mida tahab ja tagastab tulemuse
add_filter( 'the_content', 'petskratt_rAndOmcASe' );
 
function petskratt_rAndOmcASe( $content ) {

	$str = str_split( strtolower( $content ) );

	foreach ( $str as &$char ) {
		if ( rand( 0, 1 ) ) {
			$char = strtoupper( $char );
		}
	}

	return implode( '', $str );
}

Ja tulemus näeb välja selline:

Fuksi värvi pealkiri on postitusest Kuidas kohandada WordPressi teemat ehk alamteema (child theme) kasutamine.

Kuidas kohandada WordPressi teemat ehk alamteema (child theme) kasutamine

Avatud lähtekoodiga tarkvara puhul on lihtne võtta ette mistahes koodifail ja sinna muudatusi teha. Aga… stopp! Kuidas jääb siis tulevaste (turva)uuendustega?

Paljudel WordPressi kujundus-teemadel on olemas seadistuste paneel, mis lubab valida värve ja fonte, seadistada logo ja lehel kuvatavate tulpade arvu otse haldusliideses, ilma koodi puutumata. Vahel on aga vaja teha suuremaid muudatusi, mida on mõistlikum teha teema CSSi või lehe-templiite muutes.

Nii tasulised kui tasuta teemad saavad aga pidevalt uuendusi: parandatakse vigu kujunduses või lisatakse uute HTML+CSS standardite tugi, paigatakse turva-auke ja viiakse kood sobilikuks uuemate PHP versioonidega. Teema uuendus tähendab aga sisuliselt seda, et teema kustutatakse ja paigaldatakse uuesti ning selle käigus lähevad kõige kaduva teed ka failides tehtud muudatused.

Samal teemal räägib kolmapäeval, 09.10.2019 kell 19 algaval WordPressi meetupil Arūnas Liuiza.
Tule kohale kuulama ja küsima!

Selliste probleemide vältimiseks ongi loodud WordPressi alamteema ehk child theme funktsionaalsus. Toimib see nii:

  1. sul on paigaldatud teema, näiteks Twenty Nineteen
  2. ning sellele lisaks alamteema, mille päises on on viide põhiteemale
  3. aktiveerid alamteema
  4. WordPress otsib vajalikke faile kõigepealt alamteemast, kui ei leia siis põhiteemast

Ja sina saad muudatusi teha nii:

  1. kopeerid vajaliku faili põhiteema kataloogist alamteema kataloogi
  2. teed alamteema kataloogis vajalikud muudatused
  3. magic happens 🙂

Näiteks võiks teha järgmise alamteema, luues wp-content/themes alla kataloogi twentynineteen-child ja sinna sisse faili style.css:

/*
 Theme Name:   Twenty Nineteen Child
 Description:  A kind of pink child theme for Twenty Nineteen 
 Template:     twentynineteen
 Version:      1.0.0
*/

@import url("../twentynineteen/style.css");

h2 {
	color: fuchsia;
}

See viitab alustuseks põhiteema CSSile ning muudab seejärel kõik H2 pealkirjad roosaks.

Ja oletame, et järgmise asjana tahaks lisada lehe HTMLi päisesse Google Analyticsi koodijupi ja teha seda ilma liigseid pluginaid lisamata. See käib nii:

  1. kopeerid faili header.php põhiteema twentynineteen kataloogist alamteema kataloogi twentynineteen-child
  2. lisad vajalikud read:

Ja … toimibki!

Kui tahad proovida, siis twentynineteen-child.zip sisaldab ülalkirjeldatud alam-teemat (tõsi, header.php pead ise kopeerima) mille saad paigaldada WordPressile nii, nagu ikka: Välimuse haldusmenüüst või ise lahti pakkides ja FTP-ga üles laadides.

Loodetavasti tekib sellega mängides ka küsimus: “Aga mis siis, kui Twenty Nineteen põhiteemas header.php uueneb?”. Tõepoolest, sinu alamteema jääb kasutama ise muudetud versiooni ning muudatused tuleb käsitsi üle tuua, aga:

  1. alamteema all on õnneks mugavalt näha kõik komponendid, mida oled muutnud
  2. on üks teine, veel parem nipp: kasutades WordPressi haake ehk hooke ja filtreid, sellest räägib järgmine postitus WordPressi haakimiskohad ehk konksud ja filtrid

 

Tõmbame selle #CodeWeek’i siis käima!

5-20. oktoobril toimub üle kogu Euroopa #CodeWeek’i raames 29157 erinevat töötuba, koolitust jm sündmust eesmärgiga anda võimalikult paljudele võimalus saada aru mis loom see programmeerimine siis on… ja küllap avastavad nii mõnedki osalejad, et masinate oma soovi järgi käima panemine on üks huvitav tegevus.

Nii head ettevõtmist ei saa ju raisku lasta! Ja kuigi enamus Eestis toimuvatest CodeWeek’i sündmustest leiavad aset koolides ja lasteaedades… siis see ei pea üldse nii olema. Eriti kui mõelda selle peale, et avatud lähtekoodiga veebitarkvarad – WordPress, Joomla!, PrestaShop, Magento jne – puudutavad märkimisväärset hulka kasutajaid vähemalt HTMLi ja CSSi osas.

Üksinda igav koodi puurida?
Tule kolmapäeva õhtul SpringHub’i WordPress Meetup’ile – pealkirja Extending WordPress the CodeWeek way all võtame ette alamteemad, nutikad koodinipid ja päris oma plugina progemise!

Aga alustaks millegi lihtsa ja nädalavahetusse sobivaga – koolides on programmeerimise õpetamiseks kasutusel visuaalne programmeerimiskeel Scratch, kus saab käsu-plokke teineteise alla lohistades veidraid tegelasi liikuma panna.

Hea koht esimesteks katsetusteks on code.org – see on osaliselt eestikeelne, ei nõua sisselogimist ning näiteks KoodiTunni pisi-harjutused on igati mõistlikuks alternatiiviks Solitaire’i või MineSweeperi mängimisele (kulutavad aega, panevad natuke mõtlema ja saab harjutada hiirega klikkimist ja lohistamist).

Aga liikuv pilt on väärt rohkem kui tuhat sõna – ja täpselt nii lihtne see Scratch ongi:

Ega’s muud, kui tipa-tapa KoodiTundi – juba vanarahvas teadis öelda, et tibusid progetakse sügisel 🙂

Kas Zonel on värske PHP versioon? Alati. Aga sinul?

Kommunikeerides turvaprobleeme tasuks vältida asjatu paanika tekitamist – anna asjakohast infot ja tegele reaalsete, mitte filmistsenaariumi-riskidega.

Eile hakkas mulle erinevatest kanalitest tulema küsimusi Zone serverites kasutusel oleva PHP-alamversiooni kohta. Selle taustaks oli ühe arendusfirma poolt klientidele saadetud kiri:

Magento väljastas teadeande, et PHP’s avastati hiljuti turvaauk, mis lubab kaugkoodi täitmist andmaks täieliku kontrolli kõige üle. Siiani pole ühtegi kinnitatud rünnakut, kuid kuna Magento töötab PHP baasil soovitame kõikidel kaupmeestel võimalikult kiiresti PHP versiooni uuendada.

Turvalisuse tagamiseks võta ühendust oma projektijuhiga.

Teavituse põhjuseks on MS-ISAC 2019-087 nõuanne, mis loetleb üles hulga värskete PHP versioonidega paigatud turvanõrkusi – tõsi, ükski neist ei ole selline, mis annaks alust erakorraliseks paanikaks.

Kas see võiks mõjutada sinu veebirakendust?

Väga vähetõenäoline. Tõsi, kui anda PHP koodile (nt Magentole) ette konkreetse turvanõrkuse ärakasutamiseks sobilikud andmed, siis on tõesti võimalik kutsuda esile olukord, kus andmed käivitatakse koodina ja ründajal on võimalik server üle võtta.

Selleks peab aga küberkurjategija andmed väga spetsiifilisse kohta sokutama, nende lihtsalt otsilahtrisse või tarne-aadressiks sisestamisest ei piisa. Ehk on vaja ka turva-nõrkust Magentos või mõnes teises veebirakenduses, mis kasutajalt tulnud andmed kontrollimatult kasutusele võtab.

Seega hoopis olulisem oleks mõelda selle peale, et Magento 25. juunil väljastatud versioonid paikasid 75 turvanõrkust, nende hulgas hulga kriitilisi. Siinkohal on vahest paras hetk kasutada tuntud kaasamis-vormelit:

Hea kaupmees! Kas sinul on jaanipäevased turvapaigad paigaldamata? Kirjuta kommentaaridesse oma e-poe aadress ja võid võita auhindu, mille on välja pannud MageCart grupeeringud!

Lisaks: Magento 1.x ametlik tugi lõppeb 20.06.2020

Veelgi olulisem on mõelda selle peale, et Magento 1.x end-of-support saabub 20. juunil 2020 – pärast seda rohkem ametlikke turvapaiku ei väljastata.

Mis ilmselt pole paljudele kaupmeestele ka suuremaks mureks, sest pea iga kord, kui ma mõne poe aadressi https://www.magereport.com/ testi sisestan saan teada, et paigaldamata on kõik viimase paari aasta jooksul väljastatud paigad.

Kui ma selle väikse iroonilise märkuse tegemata jätaks… tabaks mind väga sügav masendus. Naljast paremini aitab mõistagi soovitus “Turvalisuse tagamiseks võta ühendust oma projektijuhiga.” – ja palun räägi temaga ennekõike oma e-poe tarkvara versiooni-uuendusest ja paikamisest.

Aga ikkagi, kas Zonel on värske PHP?

Otseloomulikult. Zone tugevus on meie hallatud serveriplatvorm ja sa võid olla kindel, et misiganes veebirakenduse alla jääv komponent – kernel, operatsioonisüsteem, MariaDB, Apache, PHP jne – on pideva jälgimise all. Teavitused turvanõrkustest ja paikadest jooksevad vastavale sise-chati-kanalile, nende võimalik mõju serveripargile selgitatakse välja ja sõltuvalt riskihinnangust tehakse uuendused lähima korralise hoolduse käigus või võetakse ette erakorraline hooldus.

Enamasti teeme hooldustöid öösel 01-06 vahel, aga on olnud ka juhtumeid, kus hommikul avaldatud teoreetilise ohu kohta oli lõunaks turvafoorumites levimas proof-of-concept ründekood ja kõik Virtuaalservereid majutavad serverid said restardi keset kibedat tööpäeva.

Ehk kui sinu Magento – või mistahes muu veebirakendus – on majutatud Zones, siis jagunevad vastutused niimoodi:

Meie uut ZoneOS platvormi kasutavates serverites on täna (13.09.2019) kasutusel:

PHP 5.6.40-pl6-zoneos (cgi-fcgi) (built: Aug 23 2019 12:31:16)
PHP 7.0.33-pl6-zoneos (cgi-fcgi) (built: Aug 23 2019 12:34:44)
PHP 7.1.32-pl1-zoneos (cgi-fcgi) (built: Sep  2 2019 08:57:28)
PHP 7.2.22-pl1-zoneos (cgi-fcgi) (built: Sep  2 2019 08:59:20)
PHP 7.3.9-pl1-zoneos (cgi-fcgi) (built: Sep  2 2019 08:59:57)
PHP 7.4.0RC1 (cgi-fcgi) (built: Sep  4 2019 08:59:55)

Vanemates serverites on valik selline:

PHP 4.4.9 (cgi-fcgi) (built: Sep 17 2013 03:15:34)
PHP 5.1.6 (cgi-fcgi) (built: Sep 23 2013 07:14:11)
PHP 5.2.17 (cgi-fcgi) (built: Jul 11 2016 10:55:56)
PHP 5.3.29 (cgi-fcgi) (built: Nov 10 2016 10:13:49)
PHP 5.4.45 (cgi-fcgi) (built: Nov 10 2016 10:32:41)
PHP 5.5.38 (cgi-fcgi) (built: Apr  1 2018 21:47:01)
PHP 5.6.40 (cgi-fcgi) (built: Feb  8 2019 10:00:13)
PHP 7.0.33 (cgi-fcgi) (built: Sep 13 2019 11:22:05)
PHP 7.1.32 (cgi-fcgi) (built: Sep  2 2019 22:22:28)
PHP 7.2.22 (cgi-fcgi) (built: Sep  3 2019 08:42:57)
PHP 7.3.9 (cgi-fcgi) (built: Sep  3 2019 09:33:50)

Vahet märkad? Uues ZoneOS’is ei ole enam PHP versioone, mis vanemad kui 5.6 ning seda väga proosalisel põhjusel – need on surnud. Schluss! Kaput!

Täpsemalt öeldes on tänaseks surnud ka PHP 5.6 ja 7.0 … ning PHP 7.1 turva-uuendusi antakse välja 1. detsembrini 2019 ehk napid 2.5 kuud:

Aga kas sinul on värske PHP?

Vot nüüd jõudsime olulise küsimuseni :.) Tõenäoliselt mitte.

Kuna iga uue PHP versiooniga kaob osa vanemaid funktsioone ja kohati muutub ka keele süntaks, ei saa me ise sinu veebi poolt kasutatavat versiooni vahetada ilma riskita, et veeb katki läheb.

Näiteks Magento 1.x puhul on olemas isegi PHP 7.2 tugi (kui paigaldada 2018.a lõpus välja tulnud paigad) – aga me näeme oma serverites hulgaliselt Magentosid, mis kasutavad PHP 5.6 või vanemat.

Kuna head turva-paanikat ei tohi raisku lasta, siis kordame veidi laiendatult soovitust:

Turvalisuse tagamiseks võta ühendust oma veebimeistri, -arendaja või projektijuhiga ning palu paigata veebirakendus ning viia see üle värskeimale võimalikule PHP versioonile.

Õigupoolest… saab versiooni vahetada ka ise – ja kui midagi katki läheb saab vana tagasi panna (sh juhul, kui tegemist oli tavapäraselt valikus mitte-oleva versiooniga). Iseteeninduses on juba aastaid punane nupp:

Ning kui sellel klikkida avaneb järgmine vaade:

Ouch! Ilmneb, et ka minu enda kontol oli blogiposti kirjutamise ajal vana PHP versiooni kasutavaid veebe, nii ammuseid kliente kui tööandjaid… ja sekka mõned Zone enda iidsed teenused, mis tänaseks kinni pandud.

Kuidas aga ilma katki-tegemise riskita testida, kas veeb uuema versiooniga toimivad? Sellest juba järgmisel nädalal, püsige kanalil 🙂

WAF ehk veebirakenduse tulemüür

Enamus veebilehtede vastu suunatud rünnakutest kasutab ära mõnda koodis olevat nõrkust, neist levinuimad on ebapiisav kasutajaõiguste või külastaja poolt sisestatud andmete kontroll.

Näiteks võiks kujutada ette olukorda, kus sisestades kommunaalteenuste ettevõtte näitude teatamise lehel aadressi lahtrisse ' OR 1=1;-- kuvatakse kõigi klientide aadressid ja eelmised näidud… sest täpselt selline näeb välja andmebaasi- ehk SQL-süst. Või siis tehakse WordPressi pihta päring, mis lisab õigusi mitte kontrolliva plugina seadistuste kaudu lehele külastajaid kuhugi edasi suunava Javascripti koodi.

Sellised koodi-vead on ka põhjus, miks tuleb kõike avalikus internetis kättesaadavat praktiliselt igapäevaselt uuendada: iga paigatud turvaprobleem  toob hiljemalt 24 tunni jooksul kaasa skannerite laine, mis otsivad haavatavaid veebe.

Lisaks aga on haavatavused, mis ei pruugi veel paika omada – sest arendaja pole probleemist teadlik, ei ole jõudnud seda paigata… või on paigatud, aga uuemas versioonis ja veebi ülemviimine sellele osutub töömahukaks.


Veebirakenduse tulemüür

Sellistel puhkudel võib abi olla veebirakenduse tulemüürist ehk WAFist (web application firewall), mis proovib kahtlased päringud tuvastada ja blokeerida. Zone Virtuaalserverites on kasutusel ModSecurity ning nüüd saab mugavalt aktiveerida ka OWASP ModSecurity Core Rule Set (CRS) tulemüürireegleid:

Valida saab logimise või blokeerimise ja logimise vahel. Kui on plaan ja võimekus logisid analüüsida, siis tasub loomulikult alustada logimisest ning vältida ausate kasutajate häirimist vale-positiivsete tuvastustega… Aga lihtsam on lülitada blokeerimine sisse ning funktsionaalsused läbi testida.

Igal juhul soovitame kontrollida, et sisse oleksid lülitatud ka reaalajas serverisse jõudvad logid.

Umbes 10 minutiga jõuab seadistus Virtuaalserverisse ja kui seejärel proovida näiteks WP otsingusse sisestada ' OR 1=1;-- peaks tulemuseks olema Error403:

Selle tulemusel tekkiavad /logs/apache.ssl.error.log faili järgmised read (loetavuse huvides natuke puhastatud):

[2019-08-21 09:17:19.367098] [client 217.146.xx.x] ModSecurity: Warning. detected SQLi using libinjection with fingerprint 's&1;c' [file "REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "64"] [id "942100"] [data "Matched Data: s&1;c found within ARGS:s: ' OR 1=1;--"] [severity "CRITICAL"] [uri "/"] [unique_id "XVzh78ean2NKORtLccJqvgAAAAM"]

[2019-08-21 09:17:19.367352] [client 217.146.xx.x] ModSecurity: Access denied with code 403 (phase 2). Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=5,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0)

Logist on näha nii põhjus (SQLi ehk andmebaasisüst), reegli number (942100), selle trigerdanud andmed ja lisaks ka reeglit sisaldanud OWASP CRS faili nimi.

99,99% juhtudest on selline päring seotud turvanõrkuse otsimise või ärakasutamisega, aga vähemalt teoorias võib SQL-friikidele mõeldud poes olla müügil sellenimeline t-särk – samuti võiks tulemüür takistada selle blogipostituse salvestamist.

Lahenduseks on reeglite valikuline väljalülitamine. Selleks saab Virtuaalserveri halduses pea- või alamdomeeni seadetes lisada Apache direktiivide ploki, mille sisuks on loetelu reeglitest:

Vajadusel saab ühele reale sobitada ka rohkem reegleid (tühikuga eraldatuna) või numbrivahemiku (jutumärkides), hea mõte on lisada juurde #-märgiga algav kommentaari-rida ning ümbritseda blokk IfModule tingimusega:

<IfModule mod_security2.c>
  # Keelame särgiotsingut takistavad reeglid:
  SecRuleRemoveById 942100 942140 "942160-942170"
</IfModule>

Kuidas tuvastada vale-positiivseid?

Kasutaja kaebuse peale logides tuhnimine on vaevarikas töö – pealegi ei ole kuvatav veateade ilus ega informatiivne. Mina olen testimiseks kasutanud vealehte, mida kuvatakse päringu blokeerimisel ning mis saadab juhul, kui kasutaja brauseris on JavaScript olemas, teate e-postile ja/või Slacki kanalisse.

Keerulisemate rünnete puhul võib toimuda ka JavaScripti interpreteerimine, lisaks ei piira see lahendus teavituste hulka ehk seda saab kasutada siht-aadressi teavitustega ülekoormamiseks.

Vealehe koodi leiab https://github.com/zone-eu/waf-handler, seadistamis-juhised sealtsamast.

Tulemuseks sellised teavitused:

Kas WAF on hõbekuul, mis lahendab kõik veebirakenduste turvaprobleemid?

Kindlasti mitte – Clarified Security‘s veebirakenduste turvalist arendust õpetav, läbistustestimise ja punase tiimi ehk ründaja rollis veebe lammutav Elar Lang palus kindlasti lisada:

WAF on kasulik “teise liini kaitsemeetmena” ja raskendab ründe läbi viimist ning hoiab heal juhul eemal teadaolevatele turvaaukudele keskendnud skänneritega “skriptijõnglased” AGA:

WAF ei tee korda programmikoodis olevaid turvaauke, need vajavad ikkagi parandamist.

Olles olnud Elari punase veebitiimi tubli töö sihtmärk Locked Shields küberõppusel võin vaid nõustuda – tänu WAFile võib mõni teine veeb osutuda lihtsamini rünnatavaks, aga see ei muuda sind kuulikindlaks.