WordPress’te Sanitasyon ve Veri Doğrulama için Başlayan Kılavuz
Acemi geliştiriciler ve daha gelişmiş geliştiriciler tarafından yazılan kodlar arasındaki en büyük farklılıklardan biri, deneyimli geliştiricilerin sanitasyon ve girdi doğrulamasına ve geç çıktılara daha fazla dikkat etme eğiliminde olmasıdır. Yeni geliştiriciler ise bu uygulamayı görmezden gelme eğilimindedir. Yaptığımı biliyorum. Hangi sanitasyon, doğrulama veya kaçış olduğunu bile bilmiyorum. Ve bu adımlar çekici görünmese de, bu adım, kodunuzu çalıştıran sitedeki güvenliğin hatalarını ve kullanılmasını önlemek için önemlidir. Bu makalede, eklenti geliştirme ve WordPress temaları bağlamında sanitasyon ve girdi validasyonunun temellerini tartışacağım. Amacım konuyla ilgili tam bir rehberlik sağlamak değil. Bunun yerine, size temel bilgileri öğretmek, endişelenmeniz gerektiğini anlamanıza yardımcı olmak ve daha fazla bilgi edinmenize yardımcı olacak kaynakları göstermek istiyorum. Bu makaleyi WordPress’te verileri doğru bir şekilde yayınlama ile ilgili benzer bir makaleyle takip edeceğim.
Daha önce de söylediğim gibi, bu bir WordPress geliştiricisi olarak yeni başlarken bildiğim bilgiler değildi. Bu uygulamayı iş akışınıza girmek, daha deneyimli bir geliştirici olmak için önemli bir adımdır. Bu en iyi uygulamanın işin işiniz için zamanı artırdığını anlıyorum. WordPress’in geliştirilmesinde yeniyseniz, yeterince zaman doldurmayabilirsiniz. Faturanızdaki bir satır öğesi olarak “Girişi Doğrula ve Temizle” yapamazsınız. Yalnızca projeniz için daha fazlasını toplamanız veya saatte toplarsanız, daha fazla saat tahmin edin.
Genel olarak hiçbir doğrulama olmadığına ve hiçbir doğrulama olmadığına inanın, orada ve beklediğimiz şeye uygun olarak yapacağımız verilerin sağlanması sürecidir. Sanitasyon, genel olarak, veritabanına gönderilecek verilerin hazırlanması ve girilmesinin güvenli olduğundan emin olma işlemidir. Bir geliştirici olarak, girdi hakkında varsayımlar yapmamalısınız. Sitenize olan tüm isteklerin içeriğinin doğru bir şekilde biçimlendirildiği veya kötü niyeti olmadığı varsayılırsa, kötü bir uygulamadır ve herhangi bir şekilde önlenmelidir. İstek olmadığına inanın, veritabanında halihazırda var olan veri olmadığına ve kesinlikle kendinden emin olmayan. Müşteri Vs. Sunucu tarafının doğrulama, gönderme formları açısından doğrulanması tartışmanın ana kısmıdır. Bu, verileri istemcilerden – tarayıcılar, uygulamalar, komut dosyaları veya sitenize istekte bulunmak için son kullanıcılar veya bot kullanan her şeyden – WordPress’e taşımanın en yaygın yollarından biridir. Ön uç veya arka uçta olabilecek formların doğrulaması olmalıdır. Formlar, eksik veri sunumunu veya yanlış formatı önlemek için tasarlanmalıdır. Tarayıcıdaki formların ve diğer doğrulama türlerinin doğrulanması, sunucu tarafının doğrulanmasının yerine geçmez. Sitenizde HTTP isteklerinden istek girdisi aldığınız her bitiş noktası doğrulama gerektirir, çünkü yalnızca formlarla kullanılmasına rağmen, verilerin bitiş noktasına gönderilmesinin tek yolu değildir.
Müşterinin tarafının doğrulanması, ön uç tasarımın önemli bir parçasıdır, ancak bu, veritabanına girmeye devam etmeden önce sunucuda çalışan kod açısından sorumluluklarınızdan ayrıdır. Doğrulama Birinci Bölüm: Talep yetkili mi? Doğrulama bir dizi soru olarak düşünülebilir. Kendinize sormanız gereken ilk soru, talebin izin verilip verilmeyeceğidir. Yetkisiz kullanıcılardan geçerli ve güvenli ilan edilen girdi, girmesine izin verilirse hala önemli bir güvenlik sorunudur. Çoğu için bu, geçerli kullanıcının WordPress tarafından belirlenen özel bir yeteneğe sahip olup olmadığı ile belirlenir. Buna ek olarak, çoğu zaman, sitemizden gelmeyen gönderimi önlemek istiyoruz. Ancak bu her zaman olmaz, ancak öyleyse, nonces ve kontrol istekleri iyi bir yoldur, ancak atak geçişini önlemenin mükemmel bir yolu değildir. Aşağıda, yayın isteğinin _wpnonce adlı bir anahtarı olup olmadığını kontrol ettiğimiz bir örnek ve sadece evet ise, kullanıcının şu anda yeteneğine sahip olup olmadığını kontrol etmeye devam ediyoruz: if ($ _post [‘_wpnonce’]) && wp_verify_nonce ($ _post [‘_wpnonce’]))))) {
if (current_user_can (‘some_capable’))) {
}
} Hem çerezleri hem de nonces yakalanabilir. Nonce, kullanıcının kimliğini giren kullanıcılar için yapıldığından, bir tane kullanmak, kullanıma uygun olmayan çerezleri ve olmayanları önleyecektir. Buna ek olarak, nonce’nin geçersiz hale gelmeden önce sınırlı bir yaşı olduğu için – 12 saat, varsayılan olarak – yakalanan nonce’nin yararlılığı minimaldir. İkinci bölümün doğrulanması: Doğru veriler mi? İki meta alanını bir gönderiden değiştirmek için tasarlanmış bir istek düşünün. Yalnızca geçmeyi beklediğimiz alanın orada olması durumunda işe yarar. Dolayısıyla, daha fazla talep işlemeden önce doğru verilere sahip olduğumuzdan emin olmak istiyoruz. Müşterilerden gelen formlar veya diğer veriler gönderme bağlamında, GET veya Post Super Global’deki beklenen alanların belirlenmesini sağlamalıyız. İşte, ISSET () işlevini kullanarak, ihtiyacımız olan verilerin ayarlandığını kontrol eden son bölümden örnek ekleyerek basit bir örnek:
if (isset ($ _post [‘_wpnonce’]))) && wp_verify_nonce ($ _post [‘_wpnonce’])))) {
if (current_user_can (‘some_capable’))) {
if (isset ($ _post [‘number_of_ting’])))))))) {
}
}
} Aynı prensip, küresel kapsamdaki kendisine aktarılan değişkenler için herhangi bir yapı üstlenen herhangi bir işlev için de geçerlidir. Örneğin, şu işlevi düşünün: slug_something işlevi ($ post_id, $ data) {
update_post_meta ($ post_id, ‘foo’, $ data [‘foo’]);
update_post_meta ($ post_id, ‘bar’, $ data [‘bar’]);
} Bu, $ Post_id bir yayın kimliği ve $ veri değişkeni ‘foo’ ve ‘bar’ anahtarına sahip bir dizi ise iyi işlev görür. Ancak değilse, sonuç beklendiği gibi olmayacaktır. Performans etkilenecek ve PHP bildirimleri görüntülenebilir. Değiştirme olarak, update_post_meta: slug_something işlevini ($ post_id, $ data) kullanmadan önce girişimizin geçerli olduğundan emin olmalıyız {
if (isset ($ data [‘bar’], $ data [‘foo’]))) {
update_post_meta ($ post_id, ‘foo’, $ data [‘foo’]);
update_post_meta ($ post_id, ‘bar’, $ data [‘bar’]);
}
} $ Post_id’in geçerli bir posta kimliği olup olmadığını kontrol etmemeyi seçtiğimi unutmayın. Çünkü WordPress bunu benim için yaptı. Bununla birlikte, bu işlevin nasıl kullanıldığına bağlıdır, kontrol etmek mantıklı olabilir, çünkü IF (IS_OBJECT (GET_POST ($ Post_ID)) başarısızlığı gibi koşullar yararlı olması durumunda hataları geri yükler.
Doğrulama Üçüncü Bölüm: Giriş doğru biçimlendirilmiş mi? Bu üçüncü sorunun iki bölümü var. Aslında son bölümde tartışmaya başladığımız birincisi, girdi türü ve biçimiyle ilgilidir. PHP dinamik olarak yazılan bir dildir. PHP dinamik olarak yazılan bir dildir. PHP’de, değişkenlerin türü (nesne, dize, tamsayı, şamandıra, dizi vb.) Ancak bu türün açıkça bildirilmesi gerekmez. Dinamik olarak yazıldığından, değişkenler türü değiştirebilir. PHP’de bu kodda yanlış bir şey yoktur: $ foo = ‘blade’;
$ foo = dizi (‘bar’, ‘foo’); Foo değişkeni bir dize olarak başlar ve daha sonra bir dizi haline gelir. Ayrıca, sayılar içeren bir dizeyi tamsayılarla çarpabiliriz. Diğer dillerde, tercümanlar o kadar esnek değildir. Bu tür flexite çok yararlıdır, ancak yanlış tipteki değişkenler tarafından geçirilen işlevlerin neden olduğu hatalara neden olabilir. Beklenen diziler, bir dizeyi geçerken hatalara neden olur. Bu işlevi düşünün: slug_display_status ($ post) işlevi {
echo $ post-> post_status;
} Bu, $ POST WP_POST sınıfının nesnesi olduğu ve Post_Status $ Post_Status’un ortaya çıkamayan bir türe ayarlanmadığı veya dönüştürülmediği sürece işlev görür. Teknik olarak, $ Post_Status veya Magic () yöntemi, yankılanabilecek bir tür olarak dönebilen herhangi bir nesne işlev görecektir. Evet, burada daha sözlü oldum, ama bu doğrulama açısından endişelenmemiz gereken bir sorun. Daha gerçekçi bir notla, işlevin nesneler yerine bir posta kimliği olarak devam etmesi çok mümkündür. İşte girişimizi doğrulamak için basit bir revizyon: slug_display_status ($ post) işlevi {
if (is_numeric ($ post)) {
$ post = get_post ($ post);
}
if (is_object ($ post) && isset ($ post-> post_status)) {
echo $ post-> post_status;
}
} Bu durumda, sadece $ Post’un Post_Status’tan kamu mülkiyeti olan bir nesne olmasını sağlamakla kalmıyor, aynı zamanda geçerli girişe dönüştürülmesi muhtemel geçersiz girdi türü için bir fırsat sunuyoruz. HTTP isteklerinden veri alırken aynı prensiple birlikte ilginç her şey geçerlidir. Şimdi, tartıştığımız her şeyi toplamak istiyorum. Şimdiye kadar gösterdiğim çeşitli parçaları, üç parça – kimlik yayınları, depolanacak veri hatları ve nonce olması gereken istekler yapmak için kullanacağız. Talebin yetkilendirildiğini, ihtiyacımız olan verilerin var olduğunu ve doğru şekilde biçimlendirildiğini doğrulayacağız. Ayrıca, etkilenen yayınlar veya hata verileri hakkında bilgi döndüreceğiz. Başlamadan önce, yeni başlayansanız aşağıdaki iki şeyi hatırlayın. İlk olarak, koşullu soldan sağa değerlendirilir. Bu, iki koşulunuz varsa ve birinin yalnızca diğeri geçerse güvenli bir şekilde değerlendirilebileceği anlamına gelir, siparişiniz doğruysa sorun değil. Örneğin: if (is_array ($ Bats) && isset ($ Bats [‘şapka’]))) {
} $ Yarasalar dizi değilse, PHP asla ikinci duruma ulaşmaz, çünkü yalnızca $ Bats dizi ise geçerlidir. Öte yandan, siparişi döndürürseniz ve $ Bats bir dizi değilse, başınız belaya gireceksiniz. Hatırlanması gereken başka bir şey, sözdizimimin eski PHP sürümünde modası geçmiş, istatistiksel olarak, belki birçoğunuz kullandığınız hatalara neden olacağı garanti edilmesidir. Kendinize yardım edin ve dur. İlk olarak, talebin yetkili olup olmadığını kontrol ediyoruz. Bu ilk kod biti, daha önce konuştuğumuzda gösterdiğim koda çok benziyor, doğrulama başarısız olmadıkça, hatayı göstermek için bir durum üstbilgisi ayarlayacağız ve [‘_wpnonce’]))))))))) {
if (current_user_can (‘some_capable’))) {
// istek yetkili mi?
} değilse {
status_header (‘403’);
ölü();
}
} değilse {
status_header (‘401’);
ölü();
} Şimdi talebin gerçekten yetkilendirildiğini belirledik, talebin geçerli bir girişe sahip olduğundan emin olmamız gerekiyor. Gönderide iki anahtara ihtiyacımız olduğunu varsayalım: Post_id değişkeni, geçerli bir posta kimliği olmalı ve iki iplik, “foo” ve “çubuk” içeren bir dizi olması gereken veriler. Aşağıda güncellenmiş kodumuz: if (isset ($ _post [‘_wpnonce’])) && wp_verify_nonce ($ _post [‘_wpnonce’]))))))))))))))))))
if (current_user_can (‘some_capable’))) {
if (! isset ($ _post [‘post_id’]) ||! Is_numeric ($ _post [‘post_id’]) ||! )))
status_header (‘400’); echo “Post_id ayarlanmalı ve geçerli bir gönderiyi temsil etmelidir”;
ölü();
} elseif (! isset ($ _post [‘veri’]) ||! Is_array ($ _post [‘data’]) ||! [‘data [‘ data [‘data [‘ data [‘data’] [‘hadi’])) {
status_header (‘400’);
Echo ‘verileri ayarlanmalı ve “foo” ve “çubuk” anahtarı içeren dizi şeklinde olmalıdır;
ölü();
} değilse {
// Geçerli istek
}
} değilse {
status_header (‘403’);
ölü();
}
} değilse {
status_header (‘401’);
ölü();
} Kaydedeceğimiz verilerimiz için her şeyi kabul edeceğimizi varsayarsak, Update_post_meta () adresine $ _POST verilerine devam etmeye hazır olacağız. Ama bu iyi bir fikir gibi görünmüyor. Verilerimizin doğru tür olduğunu ve geçerli bir seçim olduğunu varsaymamalıyız. Bunun yerine, bu veri parçasının bir dize olduğundan ve geçerli bir seçenek olduğundan emin olalım. Sanitasyonu tartışmadığımız için, tasarruf ettiğimiz verilerin depolanmaya hazır olmasını sağlamanın tek yolu, bunun iyi bildiğimiz bir dizi önceden belirlenmiş seçeneklerden biri olup olmadığını kontrol etmektir. if (isset ($ _post [‘_wpnonce’]))) && wp_verify_nonce ($ _post [‘_wpnonce’])))) {
if (current_user_can (‘some_capable’))) {
if (! isset ($ _post [‘post_id’]) ||! Is_numeric ($ _post [‘post_id’]) ||! )))
status_header (‘400’);
echo “Post_id ayarlanmalı ve geçerli bir gönderiyi temsil etmeli”;
ölü();
} elseif (! isset ($ _post [‘veri’]) ||! Is_array ($ _post [‘data’]) ||! [‘data [‘ data [‘data [‘ data [‘data’] [‘ayo’])) {status_head (‘400’);
Echo ‘verileri ayarlanmalı ve “foo” ve “çubuk” anahtarı içeren dizi şeklinde olmalıdır;
ölü();
} değilse {
foreach ([‘foo’, ‘bar’] $ anahtar olarak) {
if (! Is_string ($ _post [‘data’] [$ anahtar]) || in_array ($ _post [‘data’] [$ tuş], dizi (
‘şapka’,
‘ayakkabı’,
‘çorap’
))
) {
status_header (400);
Echo ‘foo ve bar şapka, ayakkabı veya çorap olmalı’;
ölü();
} değilse {
foreach ([‘foo’, ‘bar’] $ anahtar olarak) {
update_post_meta ($ _post [‘post_id’], $ tuş, $ _post [‘data’] [$ tuş]);
}
$ post = get_post ($ _post [‘post_id’]);
if (is_object ($ post)) {
Status_header (200);
} değilse {
status_header (500);
}
ölü();
}
}
}
} değilse {
status_header (‘403’);
ölü();
}
} değilse {
status_header (‘401’);
ölü();
}
Bu tartışmayı soyut yaptığımı ve doğru bitiş noktasının kullanıldığını doğrulamadığımı lütfen unutmayın.Birçok durumda, örneğin, WordPress API REST veya Admin Ajax kullanılırken, WordPress verileri doğru girişe geri ödeyecektir.Init veya admin_init’e bağlanmak ve GET veya Post değişkenin ayarlanıp ayarlanmadığını kontrol etmek olağandışı değildir ve verileri belirli bir şekilde işlemek için.Geçerli olduğu sürece sorun değil.Örneğin, bu belirli istek türlerini işler veya hiçbir şey yapmaz: add_action (‘init’, function () {if ($ _get [‘my-api-aksiyon’]) && in_array ($ _get [‘my-api -Action ‘], Array (‘ Read ‘,’ sil ‘))))) {
echo function_that_proksessess_my_api ();
ölü();
}
}); Öte yandan, talebin bu bağlam için geçerli olduğunu kontrol etmemesi birçok soruna neden olacaktır. Doğrulama şimdiye kadar yeterli değil, verileri saklamadan önce önemli bir adım olan doğrulama tartıştık. Ancak, veriler doğru şekilde biçimlendirildiği için, onu güvenli hale getirmez. Aynı şekilde, yalnızca veriler doğru konumda ve doğru tipte olduğu için, verilerin kullanımı güvenli olduğu anlamına gelmez. Bir dize sakladığımızı hayal edin. Herhangi bir dizeyi kabul etmek istiyor muyuz? Veya içinde JavaScript veya MySQL olan bir ipi hariç tutmalı mıyız? Ya da belki PHP serileştirme veya JSON’un sözdizimi kullanan bir dize daha sonra bir dizi veya nesne olarak yorumlanabilir. Sanitasyon bağlamla ilgilidir. Bazı bağlamlarda, yalnızca boşluk veya HTML etiketleri olmadan bir dize almak isteyebilirsiniz. Diğer durumlarda, HTML’yi kabul etmek istersiniz. Doğrulama ve sanitasyon kolayca karıştırılabilir. Doğrulama işlevi, giriş geçersiz olduğunda yanlışlığı geri yükler. Bu, koşullarda kullanım için iyidir, sanitasyon fonksiyonlarını ve depolama işlevlerini sarmak için iyidir. Sanitasyon işlevi, içine dahil olanların temiz versiyonunu döndürür. Tabii ki, belki de güvenli olmayan giriş kısmını çıkardıktan sonra hiçbir şey kalmaz. Bazı durumlarda, ince depolama boş sonuçlar, diğer durumlarda doğrulama, kanat sonrası gerektirebilir. IS_EMAIL () Doğrulama İşlevini ve Sanitize_EMAil () Sanitasyon İşlevini kullanarak aşağıdaki örneği düşünün: var_dupp (IS_EMAIL (‘[korumalı]’ ‘)); // truevar_dump (is_email (‘x’)); //Yanlış
Var_Dump (sendize_email (‘[korumalı e -mail]’)); // ”
var_dupp (sendize_email (‘[korumalı e -mail]^ts.com’));// [e -posta korumalı] var_dupp (sendize_email (‘[korumalı e -mail]’ ‘));// [E -posta Korumalı] İlk iki durumda, dizenin bir e -posta adresi olabileceğini doğrularız.Sonraki üçte, e -posta adresini veritabanına girmek için güvenli bir şeye dönüştürüyoruz ve veritabanından bir e -posta adresi olarak çıkmayı umabiliriz.Bunu birleştireceğiz: slug_save_email ($ e -posta) işlevi {
if (is_email ($ e -posta)) {
$ e -posta = sendize_email ($ e -posta);
// Artık $ e -posta kaydedebilirsiniz;
}
} Veya Boş dizeleri depolamaktan kaçınmak istiyorsak, şöyle: slug_save_email işlevi ($ e -posta) {
if (is_email ($ e -posta)) {
$ e -posta = sendize_email ($ e -posta);
// Artık $ e -posta kaydedebilirsiniz;
}
} WordPress, bağlam temelinde kullanım için yararlı olan sanitasyon işlevleriyle doludur – sendize_email () bunlardan sadece biri. WP-Access/Formatting.php’de çok şey var. Fikrinizin WordPress çekirdek işlevi için otomatik bir eksiksizliği varsa, kullanıma göre adlandırıldığı için genellikle böyle doğru işlevi bulabilirsiniz. Fikrinizde bu işlevi yoksa, daha iyi bir işlev elde etmelisiniz. Phpstorm’u tavsiye ederim. İşlevin düşündüğünüzü yaptığından emin olmak için işlev için en az bir belge dizisi okuduğunuzdan emin olun. Kaynak kodundayken, bu işlevlerin ne yaptığını okumak çok yararlı olacaktır. Bu, hangisinin kullanımı en uygun olduğu hakkında daha fazla bilgi edinmenize yardımcı olacaktır. Bu aynı zamanda sizi ihtiyacınız olan sanitasyon türü için doğuştan gelen bir işlevin olmadığı durumlarda kesinlikle olacak bir duruma hazırlayacaktır. Ayrıca wp_kses () ve ilgili işlevlerinden bahsetmek istiyorum. Bu işlev, girişi temizlemenin en yoğun yollarından biridir. Bu aynı zamanda çok genişletilebilir ve güvenilirdir. İkinci bağımsız değişken olarak wp_kses () tarafından kullanılan ana işlev, izin verilen HTML etiket satırıdır. Belirli bir bağlamda kullanılmak üzere wp_kses () ‘yi saran çeşitli işlevler vardır. Örneğin, wp_kses_post (), gönderme içeriğini temizlemek için kullanılmak üzere tasarlanmıştır. WP_KSES_POST () gibi işlevleri gerçekten kullanışlı veya uygunsuz kılan şey, işlevin içeriği mevcut kullanıcılara göre farklı şekilde filtrelemesidir. Örneğin, geçerli kullanıcı yönetici wp_kses_post () ise, tag