Bu yaptığı kadar kolay XSS ve SQL Injection engelliyor

6 Cevap php

Question: XSS (cross-site scripting) engelliyor gibi basit herhangi kaydedilmiş giriş alanlarında strip_tags kullanarak ve her türlü görüntülenen üzerine htmlspecialchars çalışıyor çıktı ... ve deyimleri SQL Injection PHP PDO kullanarak hazırlanan engelliyor?

İşte bir örnek:

// INPUT: Input a persons favorite color and save to database
// this should prevent SQL injection ( by using prepared statement)
// and help prevent XSS  (by using strip_tags)
$sql = 'INSERT INTO TABLE favorite (person_name, color) VALUES (?,?)';
$sth = $conn->prepare($sql);
$sth->execute(array(strip_tags($_POST['person_name']), strip_tags($_POST['color'])));


// OUTPUT: Output a persons favorite color from the database
// this should prevent XSS (by using htmlspecialchars) when displaying
$sql = 'SELECT color FROM favorite WHERE person_name = ?';
$sth = $conn->prepare($sql);
$sth->execute(array(strip_tags($_POST['person_name'])));
$sth->setFetchMode(PDO::FETCH_BOTH);
while($color = $sth->fetch()){
  echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8');
}

6 Cevap

Hatta daha basit. Sadece htmlspecialchars() kullanıcı kontrollü girişi yeterlidir. strip_tags() sadece yararlı olduğunu zaten sık sık gerçek dünyada kullanılan hangi değil, / işlemeden önce veri dezenfekte veritabanına kaydetmek istiyorum. HTML kodu PHP kaynağı zarar vermez, ama eval() olmayan dezenfekte kullanıcı kontrollü girişi ya da kötü şeyler bu tür kullanırsanız PHP kodu bunu yapabilirsiniz.

Ancak bu SQL injections sizi kurtarmak değil, ama bu başka bir hikaye.

Update: magic quotes kullanıcı kontrollü girişi önlemek için istek clean kullanıcı girişi almak için, aşağıdaki işlevi kullanabilirsiniz:

function get_string($array, $index, $default = null) {
    if (isset($array[$index]) && strlen($value = trim($array[$index])) > 0) {
         return get_magic_quotes_gpc() ?  stripslashes($value) : $value;
    } else {
         return $default;
    }
}

: olarak kullanılabilecek

$username = get_string($_POST, "username");
$password = get_string($_POST, "password");

(Eğer get_boolean, get_number için simliar yapmak, get_array, vb olabilir)

Önlemek için SQL sorgusu hazırlamak için SQL injections, yapın:

$sql = sprintf(
    "SELECT id FROM user WHERE username = '%s' AND password = MD5('%s')",
        mysql_real_escape_string($user),
        mysql_real_escape_string($password)
); 

XSS önlemek için kullanıcı kontrollü girişini görüntülemek için, yapın:

echo htmlspecialchars($data);

Bu kullanıcı verilerini kullanmak istiyorsanız nerede ve nasıl bağlıdır. Eğer verilerinizi eklemek istediğiniz bağlam ve bu bağlamın meta karakterleri bilmeniz gerekir.

Sadece kullanıcı web sitenizde metni koymak için izin isterseniz, htmlspecialchars HTML meta karakterleri kaçmak için yeterlidir. Belirli HTML izin vermek istediğiniz veya (a A / IMG elemanı bir URL gibi) varolan HTML elemanlarının kullanıcı verilerini gömmek istiyorsanız, htmlspecialchars olduğunu artık ama URL bağlamında HTML bağlamında değil konum olarak yeterli değildir.

Yani <script>alert("xss")</script> bir görüntü URL alanına giren verecektir:

<img src="&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt" />

Ama javascript:alert("xss") başaracaktır girerek:

<img src="javascript:alert(&quot;xss&quot;)" />

İşte XSS (Cross Site Scripting) Cheat Sheet kullanıcı veri içeri enjekte edilebilir kapsamları görmek için muhteşem bir göz atmalısınız

strip_tags gerekli değildir. Bazı kullanıcıların kendi metinlerinde < ve > kullanmak isteyebilirsiniz çünkü çoğu durumlarda strip_tags olarak, sadece rahatsız edici. (Ya da isterseniz htmlentitiesi) tarayıcıya metinleri yankı önce sadece htmlspecialchars kullanın.

(Eğer veritabanı içine hiçbir şey sokmayın önce mysql_real_esacpe_string unutmayın!)

Evet, PDO ifadeleri kullanarak hazırlanmış bir SQL enjeksiyonu korur. SQL enjeksiyonu saldırısı saldırgan tarafından sunulan veri sorgunun bir parçası olarak kabul edilir olduğu gerçeğine dayanmaktadır. Örneğin, saldırgan dize "a 'ya da' a '=' a" gönderdiğinde onun şifre olarak. Bunun yerine bütün dize veritabanındaki şifreleri ile karşılaştırıldığında olma, onu sorguya dahil, böylece sorgu SELECT * "olur kullanıcıları WHERE login = 'Joe' AND password = 'a' veya 'a' = 'a' ". Saldırgan giriş kısmı sorgunun bir parçası olarak yorumlanır. Ancak hazırlanan tablolar durumunda, sorgu hangi kısmı, özellikle SQL motoru söylüyorum, ve hangi kısmı olan (parametreleri ayarlayarak) veri, bu nedenle böyle bir karışıklık mümkündür.

Hayır, strip_tags kullanarak her zaman cross-site scripting sizi korumaz. Aşağıdaki örneği inceleyin. Senin sayfa içeriyor diyelim:

<script>
location.href='newpage_<?php echo strip_tags($_GET['language']); ?>.html';
</script>

Saldırgan ayarlanmış "dil" ile isteği gönderdiğinde "'; somethingevil ();'". (bunu hiçbir etiketleri vardır) gibi strip_tags () bu verileri döndürür. Üretilen sayfa kod olur:

<script>
location.href='newpage_';somethingevil();'.html';
</script>

somethingevil () idam olur. Gerçek XSS ile somethingevil replace () Yararlanma kodu.

Bu tek tırnak kaçış olacak çünkü htmlspecialchars'dan ile son örneği (), bu bir karşı koruyacaktır. Ancak ben bile bir alıntı dize içinde değil JavaScript kodu, iç kullanıcı tarafından sağlanan verilerin hatta tuhaf gördük. Ben değişken veya işlev adı olduğunu düşünüyorum. Bu son durumda kaçan hiçbir miktarı muhtemelen yardımcı olacaktır. Ben JavaScript kodu oluşturmak için kullanıcı girişi kullanarak önlemek için en iyi olduğuna inanıyoruz.

Basit cevap: hayır

Uzun cevap: o PHP strip_stags kaçınamaz xss enjekte yolu vardır.

Daha iyi koruma deneme için HTML purifier

Genel kural / mem "Çıkışı Escape, Filtre Girdi" dir. Herhangi bir HTML kaldırmak için girişine strip_tags kullanarak giriş filtreleme için iyi bir fikir, ama sen izin ne giriş mümkün olduğunca sıkı olmalıdır. Bir giriş parametre yalnızca bir tamsayı olması gerekiyordu Örneğin, yalnızca sayısal girdiyi kabul etmek ve her zaman onunla anything yapmadan önce bir tamsayıya dönüştürmek. İyi onaylanıp giriş filtreleme kütüphane burada size çok yardımcı oluyor; Belirli bir çerçeveye özgü olmayan biri (ben yazdım ki, bu yüzden biraz önyargılı değilim) Inspekt olduğunu.

Çıkışı için, htmlspecialchars should XSS saldırıları, but only if you pass the correct parameters kaçmak mümkün. Sen alıntı öncelemeli stili and bir charset geçmelidir.

Genel olarak, bu should XSS saldırıları kaldırın:

$safer_str = htmlspecialchars($unsafe_str, ENT_QUOTES, 'UTF-8');

İkinci parametre olarak ENT_QUOTES geçmeden, tek tırnak karakter kodlanmış değildir. Doğru charset (tipik olarak UTF-8 yeterli olacaktır) geçmedi ek olarak, XSS saldırıları gösterilmiştir. htmlspecialchars always ENT_QUOTES ve charset parametresi ile aranmalıdır.

PHP 5.2.12 a multibyte XSS attack için bir düzeltme içerdiğini unutmayın.

Sen bulabilirsiniz PHP sürümü AFAIK tam olmasa da, OWASP ESAPI PHP port ilginç ve kullanışlı.