Giriş satinization içinde preg_match güvenli enaught mi?

6 Cevap php

Telefon, ad, soyadı; preg_match tüm metin tabanlı alanlar (aka değil html alanlar için (tabii + hazırlanan deyim,) kullanıcının giriş doğrulama için güvenilir olabilir eğer merak, yeni bir web uygulaması, LAMP çevre ... im bina im , vb.).

Örneğin, klasik bir 'e-posta alanına' için, ben gibi girişini kontrol edin:

$email_pattern = "/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)" .
    "|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}" .
    "|[0-9]{1,3})(\]?)$/";

$email = $_POST['email'];
if(preg_match($email_pattern, $email)){
    //go on, prepare stmt, execute, etc...
}else{
    //email not valid! do nothing except warn the user
}

i sql / xxs enjeksiyon karşı kolay uyuyabilir?

Ben onlar gibi daha kısıtlayıcı olacak regexpi yazıyorum.

EDIT: (., Telefon, e-posta, adı, soyadı gibi) Daha önce söylediğimiz gibi, i prepared statements zaten kullanıyorsunuz ve bu davranış, sadece metin tabanlı alanlar için, yani HTML içermesine izin verilir şey (html alanlar için, i htmlpurifier kullanın).

Aslında, benim görevim bu benim sıradanifade-beyaz-liste eşleşen yalnızca giriş değerini geçmesine izin için; Başka, kullanıcıya geri döner.

p.s:: mysql_real_escape_strings olmadan bir şey arıyor im; muhtemelen proje, yakın gelecekte Postgresql geçmek, böylece çapraz-veritabanı bir doğrulama yöntemleri gerekir ;)

6 Cevap

Bir düzenli ifade filtreleme için yeterli olsun ya da olmasın düzenli ifade bağlıdır. SQL tablolarda değeri kullanmak için gidiyoruz eğer, düzenli ifade gerekir bir şekilde Disallow yılında ' ve ". HTML çıktı değerini kullanmak istediğiniz ve XSS korkuyor iseniz, size regex izin vermez emin olmak gerekir <, > ve {[(1) }].

Defalarca söylendiği gibi, hala, sen not, $ tanrı sevgi ile değil normal ifadeler güvenmek istiyorum, lütfen yok! HTML bağlamda basılmış zaman değerleri için SQL ifadeleri için mysql_real_escape_string() or prepared statements kullanın ve htmlspecialchars() .

Içeriğine göre sanitizing işlevini seçin. Genel bir kural olarak, ne olduğunu sizden daha iyi bilir ve ne tehlikeli değildir.


Lütfen düzenlemek için uyum için, düzenleyin:

Database

Hazırlanan tablolar == mysql_real_escape_string() hazırlanan ifadeleri varyant bir performans artışı olan ve yanlışlıkla değerlerden biri işlevini kullanarak unutmak mümkün olan kısa Esasen tam olarak aynı şey, içeri koymak için her değer . Hazırlanan deyimi ne olsa, yerine regex yerine, SQL enjeksiyon karşı sizi güvence oluyor vardır. Sizin regex şey olabilir ve bu hazırlanan ifadesine hiçbir fark olur.

Sen ve 'çapraz-veritabanı' mimarisi accodomate için Regexes kullanmayı deneyin gerekir olamaz. Yine, genellikle sistem ne olduğunu daha iyi bilir ve bunu daha bunun için tehlikeli değildir. Hazırlanmış ifadeler iyi ve bu değişim ile uyumlu olup olmadığını, sonra kolay uyuyabilir. Regexes olmadan.

Değiller ve sen, senin bir veritabanına özel $db->escape() mysql_real_escape_string() için MySQL mimarisi haritalarda hangi ve PostgreSQL mimarlık haritalarda bir etmek gibi bir şey bir soyutlama katmanı kullanmanız gerekiyorsa PostgreSQL için ilgili yöntem (Üzgünüm, PostgreSQL ile çalıştı değil, o el kapalı olacağını bilmiyoruz).

HTML

HTML Arıtma HTML çıktısı (Eğer ayarlama gemileri olduğu beyaz liste modunda kullanmak şartıyla) sterilize etmek için iyi bir yoldur, ancak bir {[arama beri sadece, kesinlikle HTML korumak için gereken şeyler olduğunu kullanmalısınız o şeyi ayrıştırır ve titizlik hedefleyen şekillerde ve kurallar bir dizi güçlü yoluyla manipüle beri (0)]}, oldukça maliyetlidir. Eğer korunacak HTML gerekmez Yani, kullanmak isteyeceksiniz htmlspecialchars(). Ama sonra, yine, bu noktada, düzenli ifadeler sizin kaçan ilgisi olurdu ve her şey olabilir.

Security sidenote

Actually, my mission is to let pass the input value only if it match my regexp-white-list; else, return it back to the user.

Bu senaryo için geçerli olmayabilir, ama sadece gibi genel bilgiler: 'geri kullanıcıya kötü girdi dönen' felsefesi reflected XSS saldırılara sizi açma riskini çalışır. Kullanıcı her zaman saldırgan değildir, bu nedenle kullanıcıya şeyleri dönen zaman, hepsi aynı kaçış emin olun. Sadece bir şey akılda tutmak.

For SQL injection, you should always use proper escaping like mysql_real_escape_string. The best is to use prepared statements (or even an ORM) to prevent omissions. You already did those.

Gerisi sizin uygulamanızın mantığına bağlıdır. Doğru bilgi mi çünkü doğrulama ile birlikte HTML filtre olabilir, ama ben XSS korumak için doğrulama yapmak değil, ben sadece * iş doğrulama yapmak.

Genel Kural "filtre /, giriş doğrulamak çıktı kaçış" dir. Bu yüzden kayıt değil, ne ben gösterilecek ne kaçmak (veya üçüncü tarafa iletmek) HTML etiketlerini önlemek için.

* Yine de, bir kişinin adını veya e-posta adresi içermemelidir < >

Validation giriş verileri belirli uygulama için beklenen değerlere uygun yapma ile ilgisi olduğunu.

Enjeksiyonlar Bir ham metin dizesi alarak ve uygun olmayan farklı bir bağlam içine koyarak ile ilgisi vardır Escaping.

Onlar farklı aşamalarında, ayrı ayrı baktı gereken iki tamamen ayrı konulardır. Doğrulama girişi (genellikle script başında) okunduğu zaman yapılması gereken; Bir değişmez SQL dizesi, HTML sayfası veya bazı karakterler out-of-band anlamları başka bir bağlamda gibi bir bağlam içine metin eklemek anda yapılması gerektiğini kaçan.

Bu iki süreç conflate olmamalı ve aynı anda iki konuyu işleyemez. Kelime 'sanitization' her ikisinin karışımını ima, ve gibi hemen kendi içinde şüpheli edilir. Girişler 'ayıklanmış', onlar uygulamanın özel ihtiyaçlara uygun olarak valide edilmelidir olmamalıdır. Bir HTML sayfası içine dökülmektedir eğer Daha sonra, onlar yolda HTML-kaçtı olmalıdır.

Bu senaryonun başlangıcında tüm kullanıcı girişi genelinde SQL veya HTML-kaçan çalıştırmak için yaygın bir hatadır. (Aptallar tarafından yazılmış), hatta 'security' odaklı öğreticiler genellikle bu yapıyor tavsiye. Çok ve bazen hala savunmasız - Sonuç değişmez büyük bir karmaşa.

Bir telefon numarası alanının örnek ile, bir dize yalnızca sayı içeren sağlanması iken kesinlikle de size güvenmemelisiniz bir yan etkisi var, HTML-enjeksiyon için kullanılabilir olamayacağını garanti edecek. Giriş aşamasında sadece karakterler HTML'de özel olan telefon numaraları hakkında bilmeniz gereken, ve olmamalıdır. HTML şablonu çıkış aşaması sadece bir dize (ve dolayısıyla her zaman htmlspecialchars() üzerine aramalısınız) yalnızca numaralarını içeren bilgiye sahip gerek kalmadan, bilmeli.

Bu arada, bu gerçekten kötü bir e-posta doğrulama regex bulunuyor. Regex yine e-posta doğrulama için harika bir araç değildir; düzgün yapmak için absurdly difficult, ama bu bir kullanıcı adı + ile herhangi bir .museum herhangi bir veya {dahil olmak üzere, pek çok mükemmel geçerli adresleri reddeder [(3)]} veya IDNA etki herhangi biri olabilir. Bu e-posta adresleri ile liberal olmak en iyisidir.

Hala bir veritabanına takmadan önce verileri kaçmak istiyorum. Kullanıcı girişi doğrulama, SQL enjeksiyon karşı en iyi korumayı yapmak için akıllı bir şey olsa hazırlanmış tablolar (hangi verileri otomatik kaçış) veya veritabanının yerel kaçan işlevini kullanarak kaçan vardır.

Güvende olmak için bir mysql veritabanına göndermeden önce kullanmaları gerektiğine inanıyoruz php fonksiyonu mysql_real_escape_string () vardır. (Ayrıca, okumak daha kolaydır.)