PHP / MySQL: kullanıcı girişi Sterilizasyon - Bu kötü bir fikir mi?

5 Cevap php

Ben istenen diğer her türlü senaryoyu getirir ve bu kullanıcı girdileri için ne yazdı biri "gitmek" senaryosu var:

foreach ($_REQUEST as $key => $value){
	if (get_magic_quotes_gpc()) 
	$_REQUEST[$key] = mysql_real_escape_string(stripslashes($value));  
	else
	$_REQUEST[$key] = mysql_real_escape_string($value); 
}

Ben herkesten bu yaklaşımı kullanmak görmedim. Için herhangi bir neden var mı?

EDIT - diziler için çalışmak için değiştirilmiştir:

function mysql_escape($thing) {
  if (is_array($thing)) {
	$escaped = array();
	foreach ($thing as $key => $value) {
	  $escaped[$key] = mysql_escape($value);
	}		   
	return $escaped;
  }
  // else
  if (get_magic_quotes_gpc()) $thing = stripslashes($thing);
  return mysql_real_escape_string($thing);
}

foreach ($_REQUEST as $key => $value){
	$_REQUEST[$key] = mysql_escape($value); 
}

5 Cevap

JSON, XML, Shell, MySQL, Curl, ya da HTML bu verileri kullanmak isteyebilirsiniz içeri ben yolda, kullanıldığı anda veri değil kaçmak için çok daha iyi buluyorum ve her biri kendi yolu arasında bulunuyor olacak Verileri kaçan.


Lets have a quick review of WHY escaping is needed in different contexts:

If you are in a quote delimited string, you need to be able to escape the quotes. If you are in xml, then you need to separate "content" from "markup" If you are in SQL, you need to separate "commands" from "data" If you are on the command line, you need to separate "commands" from "data"

Bu, genel olarak işlem gerçekten temel bir yönüdür. Verileri sınırlayan sözdizimi VERİ oluşabilir, çünkü kaçan, dolayısıyla SENTAKSI gelen DATA farklılaştırmak için bir yol olması gerekir.

In web programming, the common escaping cases are: 1. Outputting text into HTML 2. Outputting data into HTML attributes 3. Outputting HTML into HTML 4. Inserting data into Javascript 5. Inserting data into SQL 6. Inserting data into a shell command

Her biri yanlış kullanıldığı takdirde farklı bir güvenlik etkileri vardır. Bu gerçekten önemli! En PHP bağlamında bu gözden geçirelim:

  1. Text into HTML: htmlspecialchars(...)

  2. Data into HTML attributes htmlspecialchars(..., ENT_QUOTES)

  3. HTML into HTML Use a library such as HTMLPurifier to ENSURE that only valid tags are present.

  4. Data into Javascript I prefer json_encode. If you are placing it in an attribute, you still need to use #2, such as

  5. Inserting data into SQL Each driver has an escape() function of some sort. It is best. If you are running in a normal latin1 character set, addslashes(...) is suitable. Don't forget the quotes AROUND the addslashes() call:

    "'= Tablo1 SET alan1 INSERT INTO". addslashes ($ veri). "'"

  6. Data on the command line escapeshellarg() and escapeshellcmd() -- read the manual

-- Take these to heart, and you will eliminate 95%* of common web security risks! (* a guess)

Eğer diziler varsa $_REQUEST değerleri dezenfekte olmayacaktır.

Ben bunu yaptı ve kullanımı ettik:

<?php
function _clean($var){
    $pattern = array("/0x27/","/%0a/","/%0A/","/%0d/","/%0D/","/0x3a/",
                     "/union/i","/concat/i","/delete/i","/truncate/i","/alter/i","/information_schema/i",
                     "/unhex/i","/load_file/i","/outfile/i","/0xbf27/");
    $value = addslashes(preg_replace($pattern, "", $var));
    return $value;
}

if(isset($_GET)){
    foreach($_GET as $k => $v){
        $_GET[$k] = _clean($v);
    }
}

if(isset($_POST)){
    foreach($_POST as $k => $v){
        $_POST[$k] = _clean($v);
    }
}
?>

Sizin yaklaşım veritabanı içine yerleştirilmesi için tüm istek verileri sterilize etmeye çalışır, ama sadece çıkış de istedim ne olur? Çıktınıza gereksiz ters eğik çizgi olacaktır. Ayrıca, öncelemeli zaten SQL istisnalar korumak için iyi bir strateji değil. Parametrized sorguları (örn. PDO'de veya MySQLi in) kullanarak soyutlama katmanı kaçan sorunu "pass".

Apart diziler içine özyineleme ve tamsayılar, diyelim ki, gereksiz kaçan eksikliği, bu yaklaşım sanitasyonuyla önce deyiminde kullanmak için veri kodlar. mysql_real_escape_string() veri kaçar, onu sterilize değil - aynı şey değildir kaçan ve sanitasyon.

Sanitization görev çok PHP komut kullanmadan önce kabul edilebilirlik için giriş verileri inceliyordu bir olması. Ben bunu daha iyi kaçtı verilerle yapılır olduğunu düşünüyorum. O SQL geçene kadar ben genellikle verileri kaçış yok. Kullanmak isteyenler Prepared Statements aynı bu şekilde elde.

Bir şey daha: veri girişi utf8 dizeleri içerebilir varsa, bu kaçan önce doğrulanmış olması gerektiğini görünüyor. Ben sık sık sanitasyonuyla önce $ _POST yinelemeli utf8 temizleyici kullanın.