Dikkatli Olun: Sitenizi Güvensiz Hale Getirebilecek PHP ve WordPress İşlevleri

Yayınlanan: 2022-03-10
Kısa özet ↬ WordPress'te yeni bir eklenti dağıtmadan önce, kötüye kullanımı kolay işlevlerin bir listesini yanınızda bulundurmak iyi bir fikirdir. Daha geniş bir güvenlik stratejisinin parçası olarak kullanabileceğiniz ve kullanmanız gereken bazı işlevlere daha yakından bakalım.

Bir WordPress (veya herhangi bir) web sitesinin güvenliği çok yönlü bir sorundur. Bir sitenin güvenli olduğundan emin olmak için herkesin atabileceği en önemli adım, kötü bir şey olmamasını sağlamak için tek bir işlem veya yöntemin yeterli olmadığını akılda tutmaktır. Ama yardım etmek için yapabileceğiniz şeyler var. Bunlardan biri, olumsuz sonuçlara yol açabilecek işlevler için yazdığınız kodda ve dağıttığınız diğerlerinin kodlarında tetikte olmaktır. Bu makalede, tam olarak şunları ele alacağız: Bir WordPress geliştiricisinin kullanmadan önce açıkça düşünmesi gereken işlevler.

WordPress'in kendisi, bazıları tehlikeli olabilen oldukça büyük bir işlev kitaplığı sağlar. Bunun ötesinde, bir WordPress (PHP) geliştiricisinin, kullanıldığında tehlikeli olabilecek bir sıklıkta kullanacağı birçok PHP işlevi vardır.

Tüm bu işlevlerin meşru ve güvenli kullanımları vardır, ancak bunlar aynı zamanda kodunuzun kötü amaçlarla kötüye kullanılmasını kolaylaştırabilecek işlevlerdir. Bir güvenlik açığının nedeni olması muhtemel şeyleri ve bunları neden izlemeniz gerektiğini ele alacağız. İlk önce kodunuzdaki kötü oyuncuların kötülük için kullanabileceği PHP işlevlerini çalıştıracağız ve ardından baş ağrısına da neden olabilecek WordPress'e özgü PHP işlevlerinden bahsedeceğiz.

Dikkat Edilmesi Gereken PHP İşlevleri

Dediğimiz gibi PHP, kullanımı kolay birçok fonksiyon içerir. Bu işlevlerden bazıları, insanların onlarla kötü şeyler yapabilme kolaylığıyla ünlüdür. Tüm bu işlevlerin uygun bir kullanımı vardır, ancak bunları nasıl kullandığınıza ve bir projeye çektiğiniz diğer kodların nasıl çalıştığına dikkat edin.

Zaten sihirli tırnaklarınız olduğunu varsayacağız ve PHP sürümünüz destekliyorsa globalleri kaydetmeyi kapatmış olacaksınız. PHP 5 ve sonraki sürümlerde varsayılan olarak kapalıydılar, ancak 5.4'ün altındaki sürümler için açılabilirler. Birkaç ana bilgisayar buna izin verdi, ancak bir PHP güvenlik makalesinin onları eklemeden gerçekten tamamlanmış olduğunu düşünmüyorum.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Veya PHP 5.6'nın hala devam eden güvenlik desteğine sahip son 5.x sürümü olduğundan bahsedin. En azından üzerinde olmalısın. Ve 2018'in sonunda 5.6 desteği sona ermeden önce PHP 7'ye geçmek için bir planınız olmalı.

Bundan sonra, başa çıkmanız gereken bazı riskli işlevlere sahip olacaksınız. ile başlayan…

extract Kötü Haber, Özellikle $_POST Veya Benzeri

Neyse ki, PHP'nin extract işlevinin kullanımı büyük ölçüde gözden düştü. Kullanımının özü, onu bir dizi veri üzerinde çalıştırabilmeniz ve anahtar/değer çiftlerinin kodunuzda yaşayan değişkenler haline gelmesiydi. Böyle

 $arr = array( 'red' => 5 ); extract($arr); echo $red; // 5

çalışacaktı. Bu harika, ancak $_GET , $_POST , vb. ayıklıyorsanız da gerçekten tehlikelidir. Bu durumlarda, aslında register_globals sorununu kendiniz yeniden yaratıyorsunuz: dışarıdan bir saldırgan, bir sorgu dizesi ekleyerek değişken değerlerinizi kolayca değiştirebilir. veya form alanı. En iyi çözüm basittir: extract kullanmayın.

Çıkardığınız diziyi kendiniz oluşturursanız, extract kullanmak özellikle bir güvenlik sorunu değildir ve bazı durumlarda yararlı olabilir. Ancak tüm kullanımları, gelecekteki okuyucuların kafasını karıştırma sorununa sahiptir. Bir dizi oluşturmak ve extract çağırmak, yalnızca değişkenlerinizi bildirmekten daha kafa karıştırıcıdır. Bu yüzden, tamamen mümkün olmadığı sürece, bunun yerine manuel bildirimler yapmanızı tavsiye ederim.

Kullanıcı girişinde extract kullanmanız gerekiyorsa, her zaman EXTR_SKIP bayrağını kullanmalısınız. Bu hala kafa karışıklığı sorununa sahiptir, ancak önceden ayarlanmış değerlerinizin basit bir sorgu dizesi veya web formu değişikliği yoluyla kötü niyetli bir yabancı tarafından değiştirilebilme olasılığından kurtulur. (Çünkü zaten ayarlanmış değerleri “atlar”.)

eval ” Çünkü Keyfi Kod Korkutucudur

eval PHP'de ve onu taşıyan diğer dillerde her zaman böyle listelerde üst sıralarda yer alır. Ve iyi bir sebepten dolayı. PHP'nin PHP.net'teki resmi belgeleri bunu açıkça söylüyor:

DİKKAT : eval() dil yapısı, rastgele PHP kodunun yürütülmesine izin verdiği için çok tehlikelidir. Bu nedenle kullanımı önerilmez. Bu yapıyı kullanmaktan başka bir seçeneğin olmadığını dikkatlice doğruladıysanız, önceden uygun şekilde doğrulamadan kullanıcı tarafından sağlanan verileri bu yapıya aktarmamaya özellikle dikkat edin.

eval , programınızdaki herhangi bir rastgele dizenin PHP kodu gibi çalıştırılmasına izin verir. Bu, kendi başına bir program oluşturabilen bir program oluşturduğunuz “meta-programlama” için yararlı olduğu anlamına gelir. Aynı zamanda gerçekten tehlikelidir, çünkü rastgele kaynakların (bir web sayfasındaki bir metin kutusu gibi) hemen değerlendirme eval değerlendiricinize iletilmesine izin verirseniz, kötü niyetli bir saldırganın PHP'nin yapabileceği hemen hemen her şeyi yapmasını birdenbire önemsiz hale getirmiş olursunuz. sunucunuzda yapın. Bu, açıkçası, veritabanına bağlanmayı, dosyaları silmeyi ve bir makineye SSH'lendiğinde birinin yapabileceği hemen hemen her şeyi içerir. Bu kötü.

Programınızda eval kullanmanız gerekiyorsa, rastgele kullanıcı girişinin geçirilmesine izin vermediğinizden emin olmak için kendi yolunuzdan çekilmelisiniz. Ve keyfi kullanıcıların girişlere erişmesine izin vermeniz gerekiyorsa eval , yapabileceklerini, çalıştırmalarına izin vermediğiniz bir kara liste veya (daha iyi, ancak uygulanması çok daha zor) bir beyaz liste aracılığıyla sınırlayın. güvenli düşünün. Daha da iyisi, yalnızca doğrulanmış tamsayılar gibi yalnızca az sayıda belirli parametre değişikliğine izin verin.

Ancak PHP'nin kurucusu Rasmus Lerdorf'un şu satırını her zaman aklınızda bulundurun:

"Eğer yanıt 'eval()' ise, neredeyse kesinlikle yanlış soruyu soruyorsunuzdur."

değerlendirmede eval

İyi bilinen eval ek olarak, PHP'nin tarihsel olarak kod olarak değerlendirilen dizeleri desteklemesinin çeşitli başka yolları da vardır. WordPress geliştiricileri için en alakalı ikisi, /e değiştiricili preg_replace ve create_function . Her biri biraz farklı çalışır ve PHP 5.5.0'dan sonraki preg_replace hiç çalışmaz. (PHP 5.5 ve altı artık resmi güvenlik güncellemelerini almıyor ve bu nedenle kullanılmaması daha iyi.)

/e Regex'teki Değiştiriciler de “Kötü”dür

PHP 5.4.x veya aşağısını çalıştırıyorsanız, e ile biten PHP preg_replace çağrılarına dikkat etmek isteyeceksiniz. Şuna benzeyebilir:

 $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );)

PHP, normal ifadenizde "çitlemek" için çeşitli yollar sunar, ancak aramak istediğiniz temel şey, preg_replace ilk argümanının son karakteri olan "e"dir. Eğer oradaysa, aslında bulunan tüm segmenti satır içi eval argüman olarak geçiriyorsunuz ve ardından onu değerlendiriyorsunuz. Kullanıcı girişinin işlevinize girmesine izin veriyorsanız, bu, eval ile tamamen aynı sorunlara sahiptir. Örnek kod, bunun yerine preg_replace_callback kullanılarak değiştirilebilir. Bunun avantajı, işlevinizi yazmış olmanızdır, bu nedenle bir saldırganın değerlendirilen şeyi değiştirmesi daha zordur. Yani yukarıdakileri şöyle yazarsınız:

 // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html );

Kullanıcı create_function s Ayrıca Kötü…

PHP ayrıca create_function işlevine sahiptir. Bu artık PHP 7.2'de kullanımdan kaldırılmıştır, ancak eval çok benziyordu ve aynı temel dezavantajlara sahipti: bir dizginin (ikinci argüman) çalıştırılabilir PHP'ye dönüştürülmesine izin veriyor. Ve aynı riskleri de taşıyordu: Dikkatli olmazsanız, yanlışlıkla akıllı bir cracker'a sunucunuzda herhangi bir şey yapma yeteneği vermeniz çok kolay.

Bu, PHP'de 5.3'ün üzerindeyseniz, düzeltmesi preg_replace bile daha kolaydır. Dizeleri aracı olarak kullanmadan kendi anonim işlevinizi oluşturabilirsiniz. Bu, en azından benim gözümde hem daha güvenli hem de daha okunaklı.

assert Is Ayrıca eval -Like

assert , birçok PHP geliştiricisinin WordPress'te veya bunun dışında kullandığını gördüğüm bir işlev değil. Amacı, kodunuz için ön koşullar hakkında çok hafif iddialar içindir. Ancak aynı zamanda eval tipi bir işlemi de destekler. Bu nedenle, eval karşı olduğu kadar ona karşı da dikkatli olmalısınız. Dize tabanlı iddialar (bunun neden kötü olduğunun özü) PHP 7.2'de de kullanımdan kaldırılmıştır, bu da gelecekte daha az endişe verici olması gerektiği anlamına gelir.

Değişken Dosyaları Dahil Etmek Muhtemelen Kontrolsüz PHP Yürütülmesine İzin Vermenin Bir Yoludur

eval neden kötü olduğunu oldukça iyi araştırdık, ancak include veya require($filename'.php') gibi bir şey, özellikle $filename kullanıcı tarafından kontrol edilebilir bir değerden ayarlandığında, benzer şekilde kötü haber olabilir. Nedeni, eval tamamen farklıdır. Değişken dosya adları, WordPress dışındaki PHP uygulamalarında basit URL'den dosyaya yönlendirme gibi şeyler için sıklıkla kullanılır. Ancak bunların WordPress'te de kullanıldığını görebilirsiniz.

Sorunun özü, eklediğinizde veya require (veya include_once veya require_once ) komut dosyanızın include edilen dosyayı yürütmesini sağlar. Nadiren bu şekilde düşünmemize rağmen, aşağı yukarı, bu eval kavramsal olarak değerlendiriyoruz.

Değişkeninizin include tüm dosyaları yazdıysanız ve geldiğinde ne olacağını düşündüyseniz, sorun yok. Ancak password.php veya wp-config.php include işe yarayacağını düşünmediyseniz bu kötü bir haber. Birinin kötü amaçlı bir dosya ekleyip ardından eklemenizi yürütmesi include kötü bir haberdir (bu noktada muhtemelen daha büyük sorunlarınız olmasına rağmen).

Bunun çözümü yine de çok zor değil: sabit kod, yapabildiğiniz zaman içerir. Yapamıyorsanız, eklenebilecek bir beyaz listeye (daha iyi) veya bir kara listeye sahip olun. Beyaz listedeki dosyalar (yani, eklendiğinde ne yaptığını denetlediyseniz), güvende olduğunuzu bileceksiniz. Beyaz listenizde değilse, komut dosyanız onu içermez. Bu basit ince ayar ile oldukça güvendesiniz. Beyaz liste şuna benzer:

 $white_list = ['db.php', filter.php', 'condense.php'] If (in_array($white_list, $file_to_include)) { include($file_to_include); }

Kullanıcı Girişini Asla shell_exec ve Varyantlara Geçirmeyin

Bu büyük bir şey. PHP'deki shell_exec , system , exec ve backticks'in tümü, çalıştırdığınız kodun temeldeki (genellikle Unix) Shell ile konuşmasına izin verir. Bu, eval tehlikeli yapan ama iki katına çıkaran şeye benzer. İki katına çıkar, çünkü kullanıcının buraya dikkatsizce girmesine izin verirseniz, saldırgan PHP'nin kısıtlamalarına bile bağlı kalmaz.

PHP'den kabuk komutlarını çalıştırma yeteneği bir geliştirici olarak çok faydalı olabilir. Ancak bir kullanıcının oraya girmesine izin verirseniz, gizlice birçok tehlikeli güç kazanma yeteneğine sahiptir. Bu yüzden, kullanıcı girdisinin asla shell_exec -type işlevlerine iletilmemesi gerektiğini söyleyecek kadar ileri giderdim.

Bu tür bir durumla başa çıkmayı düşünebildiğim en iyi yol, bunu uygulamaya istekli olsaydınız, kullanıcılara küçük bir dizi güvenli, önceden tanımlanmış kabuk komutlarına erişim sağlamak olurdu. Bunu güvence altına almak mümkün olabilir . Ama o zaman bile seni çok dikkatli olman konusunda uyarırım.

unserialize İzle ; Kodu Otomatik Olarak Çalıştırır

Yaşayan bir PHP nesnesinde serialize çağırmanın temel eylemi, bu verileri bir yerde depolamak ve daha sonra bu unserialize tekrar hayata döndürmek için bu depolanan değeri kullanmak harika. Aynı zamanda oldukça yaygındır, ancak riskli olabilir. Neden riskli? Bu seri hale unserialize çağrısının girişi tamamen güvenli değilse (diyelim ki, veritabanınızda değil de bir tanımlama bilgisi olarak depolanır…), bir saldırgan, nesnenizin dahili durumunu, unserialize çağrısının kötü bir şey yapmasına neden olacak şekilde değiştirebilir.

Bu istismar, bir değerlendirme sorunundan daha eval ve fark edilme olasılığı daha düşüktür. Ancak, serileştirilmiş veriler için bir depolama mekanizması olarak bir tanımlama bilgisi kullanıyorsanız, bu veriler için serialize kullanmayın. json_encode ve json_decode gibi bir şey kullanın. Bu iki PHP ile hiçbir zaman hiçbir kodu otomatik olarak çalıştırmaz.

Buradaki temel güvenlik açığı, PHP'nin bir unserialize bir sınıfa serileştirmemesi durumunda, o sınıftaki sihirli __wakeup yöntemini çağırmasıdır. Doğrulanmamış kullanıcı girişinin __wakeup unserialized bir veritabanı çağrısı veya dosya silme gibi bir şey potansiyel olarak tehlikeli veya istenmeyen bir konuma yönlendirilebilir.

unserialize , nesneler üzerinde sihirli yöntemlerin kullanılmasını gerektirdiğinden, değerlendirme güvenlik eval farklıdır. Saldırgan, kendi kodunu oluşturmak yerine, bir nesne üzerinde önceden yazılmış yöntemlerinizi kötüye kullanmaya zorlanır. Bu OWASP Wiki sayfasının açıkladığı gibi, nesneler üzerindeki hem __destruct hem de __toString sihirli yöntemleri de risklidir.

Genel olarak, sınıflarınızda __wakeup , __destruct veya __toString yöntemlerini kullanmazsanız sorun olmaz. Ancak daha sonra birinin onları bir sınıfa eklediğini görebileceğiniz için, çağrılarınızın yakınında bulunan bir kullanıcının bu tür bir kullanım için tüm genel verileri seri hale getirmesine ve serialize json_encode unserialize json_decode ) gibi bir şey aracılığıyla iletmesine asla izin vermemek iyi bir fikirdir. asla otomatik kod yürütme değildir.

URL'leri file_get_contents ile Getirmek Riskli

Harici bir URL çağırması gereken bazı PHP kodlarını hızlı bir şekilde yazarken yaygın bir uygulama file_get_contents ulaşmaktır. Hızlıdır, kolaydır, ancak süper güvenli değildir.

file_get_contents ile ilgili sorun belirsizdir, ancak ana bilgisayarların bazen PHP'yi harici URL'lere erişmenize bile izin vermeyecek şekilde yapılandırması yeterince yaygındır. Bu sizi korumak içindir.

Buradaki sorun, file_get_contents sizin için uzak sayfaları getirmesidir. Ancak bunu yaptığında, HTTPS protokolü bağlantısının bütünlüğünü kontrol etmez. Bunun anlamı, komut dosyanızın potansiyel olarak bir ortadaki adam saldırısının kurbanı olabileceğidir ve bu da saldırganın file_get_contents sayfanızın sonucuna hemen hemen her istediğini koymasına olanak tanır.

Bu daha ezoterik bir saldırıdır. Ancak modern (Besteci tabanlı) PHP yazarken buna karşı korunmak için, daha güvenli cURL API'sini sarmak için neredeyse her zaman Guzzle kullanırım. WordPress'te daha da kolay: wp_remote_get kullanın. file_get_contents çok daha tutarlı çalışır ve varsayılan olarak SSL bağlantılarını doğrulamaya geçer. (Bunu kapatabilirsin, ama, um, belki yapma…) Daha da iyisi, ama bahsetmesi biraz daha can sıkıcı, wp_safe_remote_get , vb. Bunlar, adlarında safe_ olmadan işlevlerle aynı şekilde çalışırlar, ancak Güvenli olmayan yönlendirmelerin ve yönlendirmelerin yol boyunca gerçekleşmediğinden emin olun.

Filter_var'dan URL Doğrulamasına Körü körüne filter_var

Yani bu biraz belirsiz, bu yüzden bu WordCamp konuşmasında bunu açıkladığı için Chris Weigman'a destek. Genel olarak, PHP'nin filter_var , verileri doğrulamak veya sterilize etmek için harika bir yoldur. (Yine de ne yapmaya çalıştığınız konusunda kafanız karışmasın…)

Buradaki sorun oldukça belirgindir: URL'yi güvenli olduğundan emin olmak için kullanmaya çalışıyorsanız, filter_var protokolü doğrulamaz. Bu genellikle bir sorun değildir, ancak doğrulama için bu yönteme kullanıcı girdisini iletiyorsanız ve FILTER_VALIDATE_URL kullanıyorsanız, javascript://comment%0aalert(1) gibi bir şey başarılı olacaktır. Yani bu, hiç beklemediğiniz bir yerde temel bir XSS saldırısı için çok iyi bir vektör olabilir.

Bir URL'yi doğrulamak için, WordPress'in esc_url işlevi benzer bir etkiye sahip olacaktır, ancak yalnızca izin verilen protokollere izin verir. javascript varsayılan listede olmadığı için sizi güvende tutacaktır. Ancak, filter_var farklı olarak, kendisine geçirilen izin verilmeyen bir protokol için boş bir dize (yanlış değil) döndürür.

Gözünüzü Açık Tutmak İçin WordPress'e Özgü İşlevler

Çekirdek-PHP'nin potansiyel olarak savunmasız işlevlerine ek olarak, biraz anlaşılmaz olabilen bazı WordPress'e özgü işlevler vardır. Bunlardan bazıları yukarıda listelenen çeşitli tehlikeli işlevlere çok benzer, bazıları ise biraz farklıdır.

WordPress, maybe_unserialize ile Seriyi Kaldırıyor

Yukarıdakileri okursanız, bu muhtemelen açıktır. WordPress'te maybe_unserialize adında bir işlev vardır ve tahmin edeceğiniz gibi gerekirse kendisine iletilenleri seri hale getirir.

Bunun getirdiği yeni bir güvenlik açığı yok, sorun basitçe şu ki, tıpkı çekirdek unserialize işlevi gibi, bu da savunmasız bir nesnenin serileştirilmediğinde istismar edilmesine neden olabilir.

is_admin Bir Kullanıcı Yönetici ise Cevap Vermiyor!

Bu oldukça basit, ancak işlevin adı belirsiz ve bu nedenle insanların kafasını karıştırmaya veya aceleniz varsa kaçırılmaya eğilimlidir. WordPress'te bir eylem gerçekleştirmeye çalışan bir kullanıcının, bu eylemi gerçekleştirmek için gerekli haklara ve ayrıcalıklara sahip olup olmadığını her zaman kontrol etmelisiniz. Bunun için current_user_can işlevini kullanmalısınız.

Ancak, yanlışlıkla, is_admin mevcut kullanıcının Yönetici düzeyinde bir hesap olup olmadığını size söyleyeceğini ve bu nedenle eklentinizin kullandığı bir seçeneği ayarlayabilmesi gerektiğini düşünebilirsiniz. Bu bir hata. WordPress'te is_admin yaptığı, bunun yerine, geçerli sayfa yükünün sitenin yönetim tarafında olup olmadığını (ön tarafa kıyasla) size söylemektir. Böylece bir yönetim sayfasına ("Gösterge Tablosu" gibi) erişebilen her kullanıcı bu kontrolü potansiyel olarak geçebilecektir. is_admin geçerli kullanıcıyla değil, sayfanın türüyle ilgili olduğunu hatırladığınız sürece sorun olmaz.

add_query_arg() URL'leri Temizlemez

Bu çok yaygın değil, ancak birkaç yıl önce WordPress ekosisteminde büyük bir güncelleme dalgası vardı çünkü bu işlevlerle ilgili genel belgeler doğru değildi. Temel sorun, add_query_arg işlevinin (ve bunun tersi remove_query_arg ), bir URL'ye geçmediyse ve insanların bunu yaptığını düşünmesi durumunda site URL'sini otomatik olarak temizlememesidir. Birçok eklenti Codex tarafından yanlış yönlendirilmişti ve sonuç olarak bunu güvenli olmayan bir şekilde kullanıyordu.

Farklı yapmaları gereken temel şey: kullanmadan önce bu işleve yapılan bir çağrının sonucunu sterilize etmek. Bunu yaparsanız, olduğunu düşündüğünüz XSS saldırılarından gerçekten güvende olursunuz. Yani şuna benziyor:

 echo esc_url( add_query_arg( 'foo', 'bar' ) );

$wpdb->query() SQL Enjeksiyon Saldırısına Açık

SQL enjeksiyonu hakkında bilginiz varsa, bu aptalca görünebilir, hatta listelenmesi gereksizdir. Çünkü sorun şu ki, SQL enjeksiyon saldırılarına izin veren veritabanı sorguları oluşturmak için herhangi bir şekilde bir veritabanına (PHP'nin mysqli veya PDO veritabanı sürücülerini kullanarak) erişebilirsiniz.

$wpdb->query özellikle çağırmamın nedeni, $wpdb wpdb üzerindeki bazı diğer yöntemlerin ( insert , delete vb.) sizin için enjeksiyon saldırılarıyla ilgilenmesidir. Ek olarak, WP_Query veya benzeri ile temel WordPress veritabanı sorguları yapmaya alışkınsanız, SQL enjeksiyonunu düşünmeniz gerekmez. Bu yüzden çağırıyorum: kendi sorgunuzu yapmak için $wpdb ilk kez kullanmaya çalıştığınızda veritabanına bir enjeksiyon saldırısının mümkün olduğunu anladığınızdan emin olmak için.

Ne yapalım? $wpdb->prepare() ve ardından $wpdb->query() . Ayrıca $wpdb get_row() ve get_var() gibi diğer "alma" yöntemlerinden önce hazırlandığınızdan emin olmak isteyeceksiniz. Aksi takdirde Bobby Tables sizi yakalayabilir.

esc_sql Sizi SQL Enjeksiyonundan da Korumaz

Çoğu WordPress geliştiricisi için, esc_sql herhangi bir anlam ifade etmediğini söyleyebilirim, ancak olması gerekir. Az önce bahsettiğimiz gibi, herhangi bir veritabanı sorgusu yapmadan önce wpdb->prepare() kullanıyor olmalısınız. Bu seni güvende tutacak. Ancak bir geliştiricinin bunun yerine esc_sql ulaşması cazip ve anlaşılabilir. Ve güvenli olmasını bekleyebilirler.

Sorun, esc_sql SQL enjeksiyonuna karşı sağlam korumaya sahip olmamasıdır. Bu, yıllardır veritabanınızı korumak için kullanmaktan vazgeçtiğiniz PHP'nin add_slashes işlevinin gerçekten yüceltilmiş bir versiyonudur.

Yapacak Daha Çok Şey Var, Ama Bu Büyük Bir Başlangıç

Güvenlik açısından, yalnızca kodunuzdaki saldırganların kötüye kullanabileceği işlevleri aramaktan çok daha fazlası vardır. Örneğin, kullanıcılardan aldığınız tüm verileri doğrulamak ve sterilize etmek ve bir web sayfasına koymadan önce bu verilerden kaçmak ihtiyacını çok derinlemesine tartışmadık (gerçi yakın zamanda bu konuyla ilgili bir makale yayınladım, “WordPress'inizi Korumak Siteler Arası Komut Dosyası Çalıştırma Saldırısına Karşı Site”). Ancak bunu daha geniş bir güvenlik stratejisinin parçası olarak kullanabilir ve kullanmalısınız.

WordPress'te yeni bir eklenti dağıtmadan önce son bir inceleme yaparken bu kötüye kullanımı kolay işlevler listesini yanınızda tutmak harika bir fikir. Ancak, barındırma güvenliğinize güvendiğinizden emin olmak, kullanıcılarınızın iyi parolalara sahip olduğundan emin olmak ve çok daha fazlasını isteyeceksiniz.

Güvenlik hakkında hatırlanması gereken en önemli şey, en zayıf halkanızın önemli olduğudur. Bir alandaki iyi uygulamalar, başka bir yerde olası zayıf noktaları destekler, ancak asla tamamen düzeltemezler. Ancak bu işlevlere dikkat edin ve çoğundan yararlanacaksınız.