@ चार्ल्स बेहद सही है!
आप कई प्रकार के ज्ञात . के लिए स्वयं को जोखिम में डालते हैं जैसा कि आपने उल्लेख किया है, SQL हमले, जिनमें शामिल हैं
- एसक्यूएल इंजेक्शन:हाँ! Mysql_Escape_String शायद अभी भी आपको SQL इंजेक्शन के लिए अतिसंवेदनशील रखता है, इस पर निर्भर करता है कि आप अपने प्रश्नों में PHP चर का उपयोग कहां करते हैं।
इस पर विचार करें:
$sql = "SELECT number FROM PhoneNumbers " .
"WHERE " . mysql_real_escape_string($field) . " = " . mysql_real_escape_string($value);
क्या इस तरह से सुरक्षित और सही तरीके से बचा जा सकता है? नहीं! क्यों? क्योंकि एक हैकर अभी भी बहुत अच्छी तरह से ऐसा कर सकता है:
मेरे पीछे दोहराएं:
mysql_real_escape_string()
केवल परिवर्तनीय डेटा से बचने के लिए है, नहीं तालिका नाम, स्तंभ नाम, और विशेष रूप से LIMIT फ़ील्ड नहीं।
-
LIKE कारनामे:LIKE "$data%" जहां $data "%" हो सकता है जो सभी रिकॉर्ड लौटाएगा ... जो बहुत अच्छी तरह से हो सकता है एक सुरक्षा शोषण... क्रेडिट कार्ड के अंतिम चार अंकों के आधार पर एक लुकअप की कल्पना करें... ओह! अब हैकर्स संभावित रूप से आपके सिस्टम में प्रत्येक क्रेडिट कार्ड नंबर प्राप्त कर सकते हैं! (BTW:पूरे क्रेडिट कार्ड को स्टोर करने की शायद ही कभी सिफारिश की जाती है!)
-
चारसेट एक्सप्लॉइट्स:नफरत करने वाले चाहे कुछ भी कहें, इंटरनेट एक्सप्लोरर अभी भी . है , 2011 में, कैरेक्टर सेट एक्सप्लॉइट्स के प्रति संवेदनशील, और यह if . है आपने अपने HTML पृष्ठ को
<meta name="charset" value="UTF-8"/>
के समतुल्य के साथ सही ढंग से डिज़ाइन किया है ! ये हमले बहुत ही बुरे हैं क्योंकि ये हैकर को सीधे SQL इंजेक्शन जितना नियंत्रण देते हैं:उदा। भरा हुआ।
यह सब दिखाने के लिए यहां कुछ उदाहरण कोड दिया गया है:
// Contains class DBConfig; database information.
require_once('../.dbcreds');
$dblink = mysql_connect(DBConfig::$host, DBConfig::$user, DBConfig::$pass);
mysql_select_db(DBConfig::$db);
//print_r($argv);
$sql = sprintf("SELECT url FROM GrabbedURLs WHERE %s LIKE '%s%%' LIMIT %s",
mysql_real_escape_string($argv[1]),
mysql_real_escape_string($argv[2]),
mysql_real_escape_string($argv[3]));
echo "SQL: $sql\n";
$qq = mysql_query($sql);
while (($data = mysql_fetch_array($qq)))
{
print_r($data);
}
विभिन्न इनपुट पास होने पर इस कोड के परिणाम यहां दिए गए हैं:
$ php sql_exploits.php url http://www.reddit.com id
SQL generated: SELECT url FROM GrabbedURLs
WHERE url LIKE 'http://www.reddit.com%'
ORDER BY id;
Returns: Just URLs beginning w/ "http://www.reddit.com"
$ php sql_exploits.php url % id
SQL generated: SELECT url FROM GrabbedURLs
WHERE url LIKE '%%'
ORDER BY id;
Results: Returns every result Not what you programmed, ergo an exploit --
<ब्लॉकक्वॉट> $ php sql_exploits.php 1=1'http://www.reddit.com ' आईडी परिणाम:प्रत्येक कॉलम और प्रत्येक परिणाम देता है।
फिर वास्तव में खराब LIMIT कारनामे हैं:
$ php sql_exploits.php url
> 'http://www.reddit.com'
> "UNION SELECT name FROM CachedDomains"
Generated SQL: SELECT url FROM GrabbedURLs
WHERE url LIKE 'http://reddit.com%'
LIMIT 1
UNION
SELECT name FROM CachedDomains;
Returns: An entirely unexpected, potentially (probably) unauthorized query
from another, completely different table.
आप हमलों में एसक्यूएल को समझते हैं या नहीं यह अप्रासंगिक है। इसने जो प्रदर्शित किया है वह यह है कि mysql_real_escape_string() आसानी से . है यहां तक कि सबसे अपरिपक्व हैकर्स द्वारा भी दरकिनार किया गया। ऐसा इसलिए है क्योंकि यह एक प्रतिक्रियाशील रक्षा तंत्र है। यह केवल डेटाबेस में बहुत सीमित और ज्ञात कारनामों को ठीक करता है।
डेटाबेस को सुरक्षित रखने के लिए सभी एस्केपिंग कभी भी पर्याप्त नहीं होंगे। वास्तव में, आप प्रत्येक ज्ञात शोषण पर स्पष्ट रूप से प्रतिक्रिया कर सकते हैं और भविष्य में, आपका कोड भविष्य में खोजे गए हमलों के लिए असुरक्षित हो जाएगा।
उचित, और केवल (वास्तव में), रक्षा एक सक्रिय है:तैयार वक्तव्य का प्रयोग करें। तैयार किए गए कथनों को विशेष देखभाल के साथ डिज़ाइन किया गया है ताकि केवल मान्य और प्रोग्राम किए गए SQL को निष्पादित किया जा सके। इसका मतलब यह है कि, जब सही तरीके से किया जाता है, तो अप्रत्याशित SQL के निष्पादित होने की संभावना नाटकीय रूप से कम हो जाती है।
सैद्धांतिक रूप से, तैयार किए गए बयान जो पूरी तरह से लागू होते हैं, सभी हमलों के लिए अभेद्य होंगे, ज्ञात और अज्ञात, क्योंकि वे एक सर्वर साइड तकनीक हैं, जो डेटाबेस सर्वर स्वयं और पुस्तकालयों द्वारा नियंत्रित की जाती हैं जो प्रोग्रामिंग भाषा के साथ इंटरफेस करते हैं। इसलिए, आपको हमेशा कम से कम हर ज्ञात हैक से सुरक्षित रहने की गारंटी दी जाती है।
और यह कम कोड है:
$pdo = new PDO($dsn);
$column = 'url';
$value = 'http://www.stackoverflow.com/';
$limit = 1;
$validColumns = array('url', 'last_fetched');
// Make sure to validate whether $column is a valid search parameter.
// Default to 'id' if it's an invalid column.
if (!in_array($column, $validColumns) { $column = 'id'; }
$statement = $pdo->prepare('SELECT url FROM GrabbedURLs ' .
'WHERE ' . $column . '=? ' .
'LIMIT ' . intval($limit));
$statement->execute(array($value));
while (($data = $statement->fetch())) { }
अब यह इतना कठिन नहीं था ना? और यह सैतालीस प्रतिशत कम कोड है (195 वर्ण (पीडीओ) बनाम 375 वर्ण (mysql_)। इसे मैं "जीत से भरा" कहता हूं।
संपादित करें:सभी विवादों को दूर करने के लिए इस उत्तर ने हलचल मचाई, मुझे जो मैंने पहले ही कहा है उसे दोहराने की अनुमति दें:
<ब्लॉकक्वॉट>तैयार किए गए कथनों का उपयोग करने से व्यक्ति स्वयं SQL सर्वर के सुरक्षात्मक उपायों का उपयोग कर सकता है, और इसलिए आप उन चीज़ों से सुरक्षित रहते हैं जिनके बारे में SQL सर्वर लोग जानते हैं। सुरक्षा के इस अतिरिक्त स्तर के कारण, आप केवल भागने का उपयोग करने की तुलना में कहीं अधिक सुरक्षित हैं, चाहे कितना भी गहन क्यों न हो।