mysql - मैं PHP में एसक्यूएल इंजेक्शन कैसे रोक सकता हूं?




security sql-injection (24)

यदि उपयोगकर्ता इनपुट को SQL क्वेरी में संशोधन किए बिना डाला जाता है, तो अनुप्रयोग SQL इंजेक्शन के लिए कमजोर हो जाता है, जैसे कि निम्न उदाहरण में:

$unsafe_variable = $_POST['user_input']; 

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");

ऐसा इसलिए है क्योंकि उपयोगकर्ता value'); DROP TABLE table;-- तरह कुछ इनपुट कर सकता है value'); DROP TABLE table;-- value'); DROP TABLE table;-- , और क्वेरी बन जाती है:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

ऐसा होने से रोकने के लिए क्या किया जा सकता है?


Answers

MYSQLi इंजेक्शन को रोकने के लिए PDO और MYSQLi का उपयोग करना एक अच्छा अभ्यास है, लेकिन यदि आप वास्तव में MySQL फ़ंक्शंस और प्रश्नों के साथ काम करना चाहते हैं, तो इसका उपयोग करना बेहतर होगा

mysql_real_escape_string()

$unsafe_variable = mysql_real_escape_string($_POST['user_input']);

इसे रोकने के लिए और अधिक क्षमताएं हैं: पहचान की तरह - यदि इनपुट एक स्ट्रिंग, संख्या, चार या सरणी है, तो इसका पता लगाने के लिए बहुत सारे अंतर्निहित कार्य हैं। साथ ही, इनपुट डेटा जांचने के लिए इन कार्यों का उपयोग करना बेहतर होगा।

is_string

$unsafe_variable = (is_string($_POST['user_input']) ? $_POST['user_input'] : '');

is_numeric

$unsafe_variable = (is_numeric($_POST['user_input']) ? $_POST['user_input'] : '');

और इनपुट डेटा को जांचने के लिए उन कार्यों का उपयोग करना इतना बेहतर है mysql_real_escape_string


मैं अपने वेब एप्लिकेशन को एसक्यूएल इंजेक्शन के प्रति संवेदनशील होने से रोकने के तीन अलग-अलग तरीकों का उपयोग करता हूं।

  1. उपयोग की mysql_real_escape_string(), में एक पूर्व निर्धारित समारोह है जो PHP : है, और इस कोड में निम्न वर्णों को बैकस्लैश जोड़ने \x00, \n, \r, \, ', "और \x1a। एसक्यूएल इंजेक्शन के मौके को कम करने के लिए इनपुट मानों को पैरामीटर के रूप में पास करें।
  2. पीडीओ का उपयोग करने का सबसे उन्नत तरीका है।

उम्मीद है इससे आपको मदद मिलेगी।

निम्नलिखित क्वेरी पर विचार करें:

$iId = mysql_real_escape_string("1 OR 1=1"); $sSql = "SELECT * FROM table WHERE id = $iId";

mysql_real_escape_string () यहां सुरक्षा नहीं करेगा। यदि आप अपनी क्वेरी के अंदर अपने चर के चारों ओर सिंगल कोट्स ('') का उपयोग करते हैं तो यह आपके खिलाफ सुरक्षा करता है। इसके लिए यहां एक समाधान दिया गया है:

$iId = (int) mysql_real_escape_string("1 OR 1=1"); $sSql = "SELECT * FROM table WHERE id = $iId";

इस question बारे में कुछ अच्छे जवाब हैं।

मेरा सुझाव है, पीडीओ का उपयोग करना सबसे अच्छा विकल्प है।

संपादित करें:

mysql_real_escape_string()PHP 5.5.0 के रूप में बहिष्कृत है। या तो mysqli या पीडीओ का प्रयोग करें।

Mysql_real_escape_string () का विकल्प है

string mysqli_real_escape_string ( mysqli $link , string $escapestr )

उदाहरण:

$iId = $mysqli->real_escape_string("1 OR 1=1");
$mysqli->query("SELECT * FROM table WHERE id = $iId");

मैं पैरामीटरयुक्त SQL क्वेरी चलाने के लिए PDO (PHP डेटा ऑब्जेक्ट्स) का उपयोग करने की सलाह PDO

यह न केवल एसक्यूएल इंजेक्शन के खिलाफ सुरक्षा करता है, यह प्रश्नों को भी गति देता है।

और mysql_ , mysqli_ , और pgsql_ फ़ंक्शंस के बजाय पीडीओ का उपयोग करके, आप डेटाबेस pgsql_ को स्विच करने के लिए दुर्लभ घटना में, डेटाबेस से थोड़ा अधिक सारणी बनाते हैं।


आप कैश इंजन का लाभ लेने के चाहते हैं, जैसे Redis या Memcached , हो सकता है DALMP एक विकल्प हो सकता है। यह शुद्ध MySQLi का उपयोग करता है । इसे जांचें: PHP का उपयोग करके MySQL के लिए DALMP डेटाबेस एब्स्ट्रक्शन लेयर।

साथ ही, आप अपनी क्वेरी तैयार करने से पहले अपने तर्क तैयार कर सकते हैं ताकि आप गतिशील प्रश्न बना सकें और अंत में पूरी तरह से तैयार कथन क्वेरी हो। PHP का उपयोग कर MySQL के लिए DALMP डेटाबेस एब्स्ट्रक्शन लेयर।


इस PHP फ़ंक्शन का उपयोग करके mysql_escape_string()आप तेजी से एक अच्छी रोकथाम प्राप्त कर सकते हैं।

उदाहरण के लिए:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."'

mysql_escape_string - mysql_query में उपयोग के लिए एक स्ट्रिंग से बच निकलता है

अधिक रोकथाम के लिए, आप अंत में जोड़ सकते हैं ...

wHERE 1=1   or  LIMIT 1

अंत में आप पाते हैं:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."' LIMIT 1

एसक्यूएल कथन में विशेष पात्रों से बचने के लिए कुछ दिशानिर्देश।

MySQL उपयोग न करें , यह एक्सटेंशन बहिष्कृत है, MySQLi या PDO उपयोग करें ।

MySQLi

स्ट्रिंग में विशेष वर्णों से मैन्युअल रूप से भागने के लिए आप mysqli_real_escape_string फ़ंक्शन का उपयोग कर सकते हैं । फ़ंक्शन ठीक से काम नहीं करेगा जब तक कि सही वर्ण सेट mysqli_set_charset साथ सेट न हो ।

उदाहरण:

$mysqli = new mysqli( 'host', 'user', 'password', 'database' );
$mysqli->set_charset( 'charset');

$string = $mysqli->real_escape_string( $string );
$mysqli->query( "INSERT INTO table (column) VALUES ('$string')" );

तैयार बयानों वाले मूल्यों से स्वचालित रूप से बचने के लिए, mysqli_prepare , और mysqli_stmt_bind_param उपयोग करें जहां उचित बाध्य चर के लिए प्रकार उचित रूपांतरण के लिए प्रदान किए जाने चाहिए:

उदाहरण:

$stmt = $mysqli->prepare( "INSERT INTO table ( column1, column2 ) VALUES (?,?)" );

$stmt->bind_param( "is", $integer, $string );

$stmt->execute();

कोई फर्क नहीं पड़ता कि आप तैयार कथन या mysqli_real_escape_string का उपयोग करते हैं, तो आपको हमेशा उस इनपुट डेटा के प्रकार को जानना होगा जिसके साथ आप काम कर रहे हैं।

इसलिए यदि आप एक तैयार कथन का उपयोग करते हैं, तो आपको mysqli_stmt_bind_param फ़ंक्शन के लिए चर के प्रकार निर्दिष्ट करना होगा।

और mysqli_real_escape_string का उपयोग, जैसा कि नाम कहता है, स्ट्रिंग में विशेष वर्णों से बचने के लिए है, इसलिए यह पूर्णांक को सुरक्षित नहीं बनाएगा। इस फ़ंक्शन का उद्देश्य एसक्यूएल कथन में स्ट्रिंग को तोड़ने और डेटाबेस के नुकसान को रोकने के लिए है। mysqli_real_escape_string एक उपयोगी फ़ंक्शन है जब सही ढंग से उपयोग किया जाता है, खासकर जब sprintf के साथ संयुक्त होता है।

उदाहरण:

$string = "x' OR name LIKE '%John%";
$integer = '5 OR id != 0';

$query = sprintf( "SELECT id, email, pass, name FROM members WHERE email ='%s' AND id = %d", $mysqli->real_escape_string( $string ), $integer );

echo $query;
// SELECT id, email, pass, name FROM members WHERE email ='x\' OR name LIKE \'%John%' AND id = 5

$integer = '99999999999999999999';
$query = sprintf( "SELECT id, email, pass, name FROM members WHERE email ='%s' AND id = %d", $mysqli->real_escape_string( $string ), $integer );

echo $query;
// SELECT id, email, pass, name FROM members WHERE email ='x\' OR name LIKE \'%John%' AND id = 2147483647

जरूरी

एसक्यूएल इंजेक्शन को रोकने का सबसे अच्छा तरीका बचने के बजाय तैयार वक्तव्यों का उपयोग करना है, क्योंकि स्वीकृत उत्तर दर्शाता है।

Aura.Sql और EasyDB जैसे पुस्तकालय हैं जो डेवलपर्स को तैयार कथनों का उपयोग आसान बनाने की अनुमति देते हैं। एसक्यूएल इंजेक्शन को रोकने में तैयार कथन बेहतर क्यों हैं, इस बारे में और जानने के लिए, इस mysql_real_escape_string() बाईपास का संदर्भ लें और हाल ही में वर्डप्रेस में यूनिकोड एसक्यूएल इंजेक्शन भेद्यताएं तय करें

इंजेक्शन रोकथाम - mysql_real_escape_string()

इन हमलों को रोकने के लिए PHP ने विशेष रूप से बनाया गया कार्य किया है। आपको केवल एक फ़ंक्शन, mysql_real_escape_string के मुंह का उपयोग करना है।

mysql_real_escape_string एक स्ट्रिंग लेता है जो एक MySQL क्वेरी में उपयोग किया जा रहा है और उसी स्ट्रिंग को सभी SQL इंजेक्शन प्रयासों से सुरक्षित रूप से बचने के प्रयासों को वापस कर देता है। असल में, यह उन परेशान उद्धरणों को प्रतिस्थापित करेगा (') उपयोगकर्ता एक MySQL- सुरक्षित विकल्प, एक बच निकला उद्धरण \ "के साथ प्रवेश कर सकता है।

नोट: इस फ़ंक्शन का उपयोग करने के लिए आपको डेटाबेस से कनेक्ट होना चाहिए!

// MySQL से कनेक्ट करें

$name_bad = "' OR 1'"; 

$name_bad = mysql_real_escape_string($name_bad);

$query_bad = "SELECT * FROM customers WHERE username = '$name_bad'";
echo "Escaped Bad Injection: <br />" . $query_bad . "<br />";


$name_evil = "'; DELETE FROM customers WHERE 1 or username = '"; 

$name_evil = mysql_real_escape_string($name_evil);

$query_evil = "SELECT * FROM customers WHERE username = '$name_evil'";
echo "Escaped Evil Injection: <br />" . $query_evil;

आप MySQL - SQL इंजेक्शन रोकथाम में अधिक जानकारी प्राप्त कर सकते हैं।


पीडीओ ( mysql_कार्यों से आने ) का उपयोग करने के बारे में अनिश्चित लोगों के लिए , मैंने एक बहुत ही सरल पीडीओ रैपर बनाया जो एक ही फाइल है। यह दिखाने के लिए मौजूद है कि सभी आम चीजों को करने की ज़रूरत है कि अनुप्रयोगों को कितना आसान करना है। PostgreSQL, MySQL, और SQLite के साथ काम करता है।

मूल रूप से, इसे PDO को PDO को PDO लिए पीडीओ फ़ंक्शंस को वास्तविक जीवन में उपयोग करने के तरीके को पढ़ने के लिए इसे PDO लिए इसे सरल बनाएं ताकि आप इच्छित प्रारूप में मूल्यों को स्टोर और पुनर्प्राप्त कर सकें ।

मुझे एक कॉलम चाहिए

$count = DB::column('SELECT COUNT(*) FROM `user`);

मुझे एक सरणी (कुंजी => मान) परिणाम चाहिए (यानी एक चयन बॉक्स बनाने के लिए)

$pairs = DB::pairs('SELECT `id`, `username` FROM `user`);

मुझे एक पंक्ति परिणाम चाहिए

$user = DB::row('SELECT * FROM `user` WHERE `id` = ?', array($user_id));

मुझे परिणामों की एक सरणी चाहिए

$banned_users = DB::fetch('SELECT * FROM `user` WHERE `banned` = ?', array(TRUE));

एसक्यूएल इंजेक्शन और अन्य एसक्यूएल हैक्स को रोकने के कई तरीके हैं। आप इसे आसानी से इंटरनेट पर ढूंढ सकते हैं (Google खोज)। बेशक पीडीओ अच्छे समाधानों में से एक है। लेकिन मैं आपको एसक्यूएल इंजेक्शन से कुछ अच्छे लिंक रोकथाम का सुझाव देना चाहता हूं।

एसक्यूएल इंजेक्शन और कैसे रोकें

एसक्यूएल इंजेक्शन के लिए PHP मैनुअल

PHP में एसक्यूएल इंजेक्शन और रोकथाम का माइक्रोसॉफ्ट स्पष्टीकरण

और कुछ अन्य जैसे MySQL और PHP के साथ SQL इंजेक्शन को रोकना

अब, आपको SQL क्वेरी इंजेक्शन से अपनी क्वेरी को रोकने की आवश्यकता क्यों है?

मैं आपको बताना चाहता हूं: हम नीचे दिए गए संक्षिप्त उदाहरण के साथ एसक्यूएल इंजेक्शन को रोकने के लिए क्यों प्रयास करते हैं:

लॉगिन प्रमाणीकरण मैच के लिए क्वेरी:

$query="select * from users where email='".$_POST['email']."' and password='".$_POST['password']."' ";

अब, अगर कोई (हैकर) डालता है

$_POST['email']= [email protected]' OR '1=1

और पासवर्ड कुछ भी ....

क्वेरी को केवल सिस्टम में पार्स किया जाएगा:

$query="select * from users where email='[email protected]' OR '1=1';

दूसरा हिस्सा त्याग दिया जाएगा। तो, क्या होगा? एक गैर-अधिकृत उपयोगकर्ता (हैकर) बिना पासवर्ड के व्यवस्थापक के रूप में लॉग इन करने में सक्षम होगा। अब, वह कुछ भी कर सकता है जो व्यवस्थापक / ईमेल व्यक्ति कर सकता है। देखें, एसक्यूएल इंजेक्शन को रोका नहीं गया है, यह बहुत खतरनाक है।


जैसा कि आप देख सकते हैं, लोग सुझाव देते हैं कि आप सबसे अधिक तैयार कथन का उपयोग करें। यह गलत नहीं है, लेकिन जब आपकी क्वेरी प्रति प्रक्रिया केवल एक बार निष्पादित की जाती है, तो थोड़ा प्रदर्शन दंड होगा।

मुझे इस मुद्दे का सामना करना पड़ रहा था, लेकिन मुझे लगता है कि मैंने इसे बहुत परिष्कृत तरीके से हल किया - जिस तरह से हैकर्स उद्धरणों का उपयोग करने से बचने के लिए उपयोग करते हैं। मैंने इसे नकली तैयार बयान के संयोजन के साथ प्रयोग किया। मैं इसे सभी प्रकार के संभावित एसक्यूएल इंजेक्शन हमलों को रोकने के लिए उपयोग करता हूं।

मेरा दृष्टिकोण:

  • यदि आप इनपुट पूर्णांक होने की अपेक्षा करते हैं तो सुनिश्चित करें कि यह वास्तव में पूर्णांक है। एक चर-प्रकार की भाषा में PHP की तरह यह बहुत महत्वपूर्ण है। उदाहरण के लिए आप इस सरल लेकिन शक्तिशाली समाधान का उपयोग कर सकते हैं: sprintf("SELECT 1,2,3 FROM table WHERE 4 = %u", $input);

  • यदि आप पूर्णांक हेक्स से कुछ और उम्मीद करते हैं । यदि आप इसे हेक्स करते हैं, तो आप पूरी तरह से सभी इनपुट से बच जाएंगे। सी / सी ++ में mysql_hex_string() नामक एक फ़ंक्शन है, PHP में आप bin2hex() उपयोग कर सकते हैं।

    इस बारे में चिंता न करें कि बच निकलने वाली स्ट्रिंग में इसकी मूल लंबाई का 2x आकार होगा क्योंकि यदि आप mysql_real_escape_string उपयोग करते हैं, तो PHP को समान क्षमता आवंटित करना होगा ((2*input_length)+1) , जो वही है।

  • जब आप बाइनरी डेटा स्थानांतरित करते हैं तो यह हेक्स विधि अक्सर उपयोग की जाती है, लेकिन मुझे कोई कारण नहीं दिखता कि एसक्यूएल इंजेक्शन हमलों को रोकने के लिए सभी डेटा पर इसका उपयोग क्यों न करें। ध्यान दें कि आपको 0x साथ डेटा UNHEX करना होगा या इसके बजाय MySQL फ़ंक्शन UNHEX उपयोग करना होगा।

तो, उदाहरण के लिए, क्वेरी:

SELECT password FROM users WHERE name = 'root'

हो जाएगा:

SELECT password FROM users WHERE name = 0x726f6f74

या

SELECT password FROM users WHERE name = UNHEX('726f6f74')

हेक्स एकदम सही भाग्य है। इंजेक्ट करने का कोई तरीका नहीं है।

यूएनएचएक्स फ़ंक्शन और 0 एक्स उपसर्ग के बीच अंतर

टिप्पणियों में कुछ चर्चा हुई, इसलिए मैं अंततः इसे स्पष्ट करना चाहता हूं। ये दो दृष्टिकोण बहुत समान हैं, लेकिन वे कुछ तरीकों से थोड़ा अलग हैं:

** 0x ** उपसर्ग का उपयोग केवल डेटा कॉलम जैसे चर, वर्कर, टेक्स्ट, ब्लॉक, बाइनरी आदि के लिए किया जा सकता है
इसके अलावा, यदि आप खाली स्ट्रिंग डालने वाले हैं तो इसका उपयोग थोड़ा जटिल है। आपको इसे पूरी तरह से '' से बदलना होगा, या आपको एक त्रुटि मिलेगी।

UNHEX () किसी भी कॉलम पर काम करता है; आपको खाली स्ट्रिंग के बारे में चिंता करने की ज़रूरत नहीं है।

हेक्स विधियों को अक्सर हमलों के रूप में उपयोग किया जाता है

ध्यान दें कि यह हेक्स विधि अक्सर SQL इंजेक्शन हमले के रूप में उपयोग की जाती है जहां पूर्णांक स्ट्रिंग की तरह होते हैं और केवल mysql_real_escape_string बच जाते हैं। फिर आप उद्धरण के उपयोग से बच सकते हैं।

उदाहरण के लिए, यदि आप ऐसा कुछ करते हैं:

"SELECT title FROM article WHERE id = " . mysql_real_escape_string($_GET["id"])

एक हमला आपको बहुत आसानी से इंजेक्ट कर सकता है । अपनी स्क्रिप्ट से दिए गए निम्नलिखित इंजेक्शन कोड पर विचार करें:

चुनें ... जहां id = -1 संघ सभी info_schema.tables से table_name का चयन करें

और अब टेबल संरचना निकालें:

चुनें ... जहां id = -1 संघ सभी info_schema.column से column_name का चयन करते हैं जहां table_name = 0x61727469636c65

और उसके बाद बस जो भी डेटा चाहते हैं चुनें। क्या यह अच्छा नहीं है?

लेकिन अगर इंजेक्शन योग्य साइट का कोडर हेक्स करेगा, तो कोई इंजेक्शन संभव नहीं होगा क्योंकि क्वेरी इस तरह SELECT ... WHERE id = UNHEX('2d312075...3635') : SELECT ... WHERE id = UNHEX('2d312075...3635')


PDO और तैयार प्रश्नों का प्रयोग करें।

( $conn एक PDO ऑब्जेक्ट है)

$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();

मेरी राय में, आम तौर पर आपके PHP अनुप्रयोग (या उस मामले के लिए कोई भी वेब एप्लिकेशन) में एसक्यूएल इंजेक्शन को रोकने का सबसे अच्छा तरीका है अपने एप्लिकेशन के आर्किटेक्चर के बारे में सोचना। यदि एसक्यूएल इंजेक्शन के खिलाफ सुरक्षा का एकमात्र तरीका एक विशेष विधि या फ़ंक्शन का उपयोग करना याद रखना है जो हर बार जब आप डेटाबेस से बात करते हैं, तो आप गलत कर रहे हैं। इस तरह, यह केवल समय की बात है जब तक कि आप अपने कोड में किसी बिंदु पर अपनी क्वेरी को सही रूप से प्रारूपित करना न भूलें।

एमवीसी पैटर्न को अपनाने और CakePHP या CodeIgniter जैसे ढांचे को शायद जाने का सही तरीका है: सुरक्षित डेटाबेस क्वेरी बनाने जैसे सामान्य कार्यों को हल किया गया है और इस तरह के ढांचे में केंद्रीय रूप से कार्यान्वित किया गया है। वे आपको अपने वेब एप्लिकेशन को एक समझदार तरीके से व्यवस्थित करने में मदद करते हैं और आपको एकल SQL क्वेरी सुरक्षित रूप से बनाने के बारे में ऑब्जेक्ट्स को लोड और सहेजने के बारे में अधिक सोचते हैं।


तैयार बयान और पैरामीटरयुक्त प्रश्नों का प्रयोग करें। ये SQL कथन हैं जिन्हें किसी भी पैरामीटर से डेटाबेस सर्वर द्वारा अलग-अलग भेजा और पार्स किया जाता है। इस तरह हमलावर के लिए दुर्भावनापूर्ण एसक्यूएल इंजेक्ट करना असंभव है।

आपको मूल रूप से इसे प्राप्त करने के लिए दो विकल्प हैं:

  1. PDO का उपयोग करना (किसी समर्थित डेटाबेस ड्राइवर के लिए):

    $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    
    $stmt->execute(array('name' => $name));
    
    foreach ($stmt as $row) {
        // do something with $row
    }
    
  2. MySQLi का उपयोग (MySQL के लिए):

    $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
    $stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        // do something with $row
    }
    

यदि आप MySQL के अलावा किसी अन्य डेटाबेस से कनेक्ट हो रहे हैं, तो एक ड्राइवर-विशिष्ट दूसरा विकल्प है जिसे आप PostgreSQL के लिए संदर्भित कर सकते हैं (उदाहरण के लिए pg_prepare() और pg_execute() )। पीडीओ सार्वभौमिक विकल्प है।

कनेक्शन को सही तरीके से स्थापित करना

ध्यान दें कि एक MySQL डेटाबेस तक पहुंचने के लिए PDO का उपयोग करते समय वास्तविक तैयार कथन डिफ़ॉल्ट रूप से उपयोग नहीं किया जाता है । इसे ठीक करने के लिए आपको तैयार बयानों के अनुकरण को अक्षम करना होगा। पीडीओ का उपयोग कर कनेक्शन बनाने का एक उदाहरण है:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

उपर्युक्त उदाहरण में त्रुटि मोड कड़ाई से जरूरी नहीं है, लेकिन इसे जोड़ने की सलाह दी जाती है । इस तरह जब कुछ गलत हो जाता है तो स्क्रिप्ट Fatal Error से नहीं रुक जाएगी। और यह डेवलपर को किसी भी त्रुटि को catch का मौका देता है जो PDOException एस के रूप में throw जाता है।

अनिवार्य है , हालांकि, पहली सेट setAttribute() लाइन है, जो पीडीओ को नकली तैयार बयान अक्षम करने और वास्तविक तैयार बयान का उपयोग करने के लिए कहती है। यह सुनिश्चित करता है कि MySQL सर्वर पर भेजने से पहले कथन और मानों को PHP द्वारा पार्स नहीं किया गया है (संभावित हमलावर को दुर्भावनापूर्ण SQL को इंजेक्ट करने का कोई मौका नहीं है)।

यद्यपि आप निर्माता के विकल्पों में charset सेट कर सकते हैं, यह ध्यान रखना महत्वपूर्ण है कि PHP (<5.3.6) के 'पुराने' संस्करणों ने चुपचाप डीएसएन में वर्णसेट पैरामीटर को अनदेखा कर दिया है

व्याख्या

क्या होता है कि आपके द्वारा तैयार किए जाने वाले SQL कथन को डेटाबेस सर्वर द्वारा पार्स और संकलित किया जाता है। मानकों को निर्दिष्ट करके (या तो एक ? या नामित पैरामीटर जैसे :name ऊपर दिए गए उदाहरण में :name ) आप डेटाबेस इंजन को बताते हैं जहां आप फ़िल्टर करना चाहते हैं। फिर जब आप execute , तो तैयार कथन आपके द्वारा निर्दिष्ट पैरामीटर मानों के साथ संयुक्त होता है।

यहां महत्वपूर्ण बात यह है कि पैरामीटर मान संकलित कथन के साथ संयुक्त होते हैं, न कि SQL स्ट्रिंग। एसक्यूएल इंजेक्शन स्क्रिप्ट को ट्रिक करके दुर्भावनापूर्ण तारों में काम करता है जब यह SQL को डेटाबेस भेजने के लिए बनाता है। तो पैरामीटर से अलग से वास्तविक एसक्यूएल भेजकर, आप जिस चीज का इरादा नहीं रखते थे उसके साथ समाप्त होने का जोखिम सीमित करते हैं। तैयार कथन का उपयोग करते समय आपके द्वारा भेजे जाने वाले किसी भी पैरामीटर को केवल स्ट्रिंग के रूप में माना जाएगा (हालांकि डेटाबेस इंजन कुछ अनुकूलन कर सकता है, इसलिए पैरामीटर निश्चित रूप से संख्याओं के रूप में भी समाप्त हो सकते हैं)। ऊपर दिए गए उदाहरण में, यदि $name चर में 'Sarah'; DELETE FROM employees 'Sarah'; DELETE FROM employees परिणाम परिणाम "'Sarah'; DELETE FROM employees" स्ट्रिंग के लिए खोज होगा "'Sarah'; DELETE FROM employees" , और आप एक खाली तालिका के साथ समाप्त नहीं होंगे।

तैयार बयानों का उपयोग करने का एक अन्य लाभ यह है कि यदि आप एक ही सत्र में कई बार एक ही कथन निष्पादित करते हैं तो इसे केवल एक बार पार्स और संकलित किया जाएगा, जिससे आपको कुछ गति लाभ मिलेगा।

ओह, और चूंकि आपने एक डालने के लिए इसे कैसे किया है, इसके बारे में पूछा है, यहां एक उदाहरण है (पीडीओ का उपयोग करके):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

तैयार कथन गतिशील प्रश्नों के लिए इस्तेमाल किया जा सकता है?

जबकि आप अभी भी क्वेरी पैरामीटर के लिए तैयार कथन का उपयोग कर सकते हैं, गतिशील क्वेरी की संरचना को parametrized नहीं किया जा सकता है और कुछ क्वेरी सुविधाओं को parametrized नहीं किया जा सकता है।

इन विशिष्ट परिदृश्यों के लिए, सबसे अच्छी बात यह है कि श्वेतसूची फ़िल्टर का उपयोग करें जो संभावित मानों को प्रतिबंधित करता है।

// Value whitelist
// $dir can only be 'DESC' otherwise it will be 'ASC'
if (empty($dir) || $dir !== 'DESC') {
   $dir = 'ASC';
}

PHP और MySQL के लिए बहुत सारे उत्तर हैं , लेकिन एसक्यूएल इंजेक्शन को रोकने के साथ-साथ oci8 ड्राइवरों के नियमित उपयोग को रोकने के लिए PHP और Oracle के लिए कोड भी है:

$conn = oci_connect($username, $password, $connection_string);
$stmt = oci_parse($conn, 'UPDATE table SET field = :xx WHERE ID = 123');
oci_bind_by_name($stmt, ':xx', $fieldval);
oci_execute($stmt);

सुरक्षा चेतावनी : यह उत्तर सुरक्षा सर्वोत्तम प्रथाओं के अनुरूप नहीं है। एसक्यूएल इंजेक्शन को रोकने के लिए बचाना अपर्याप्त है , इसके बजाय तैयार कथन का उपयोग करें। अपने जोखिम पर नीचे उल्लिखित रणनीति का प्रयोग करें। (इसके अलावा, mysql_real_escape_string() को PHP 7 में हटा दिया गया था)

आप इस तरह कुछ बुनियादी कर सकते हैं:

$safe_variable = mysql_real_escape_string($_POST["user-input"]);
mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

यह हर समस्या को हल नहीं करेगा, लेकिन यह एक बहुत अच्छा कदम पत्थर है। मैंने स्पष्ट वस्तुओं को छोड़ दिया जैसे वैरिएबल के अस्तित्व, प्रारूप (संख्याएं, अक्षरों, आदि) की जांच करना।


कई उपयोगी उत्तरों के बारे में, मुझे उम्मीद है कि इस धागे में कुछ मूल्य जोड़े जाएंगे। एसक्यूएल इंजेक्शन एक ऐसा हमला है जो उपयोगकर्ता इनपुट (उपयोगकर्ता द्वारा भरने वाले इनपुट और फिर प्रश्नों के अंदर उपयोग किए जाने वाले इनपुट) के माध्यम से किया जा सकता है, एसक्यूएल इंजेक्शन पैटर्न सही क्वेरी सिंटैक्स हैं, जबकि हम इसे कॉल कर सकते हैं: बुरे कारणों से खराब प्रश्न, हम मानते हैं कि वहां हो सकता है बुरे व्यक्ति बनें जो गुप्त जानकारी (पहुंच नियंत्रण को छोड़कर) प्राप्त करने का प्रयास करते हैं जो सुरक्षा के तीन सिद्धांतों (गोपनीयता, ईमानदारी, उपलब्धता) को प्रभावित करते हैं।

अब, हमारा मुद्दा एसक्यूएल इंजेक्शन हमलों जैसे सुरक्षा खतरों को रोकने के लिए है (प्रश्न पूछने (PHP का उपयोग कर एसक्यूएल इंजेक्शन हमले को कैसे रोकें), अधिक यथार्थवादी, डेटा फ़िल्टरिंग या समाशोधन इनपुट डेटा ऐसे मामले में उपयोगकर्ता इनपुट डेटा का उपयोग करते समय मामला है प्रश्न, PHP या किसी अन्य प्रोग्रामिंग भाषा का उपयोग करना मामला नहीं है, या जैसा कि अधिक लोगों द्वारा तैयार किए गए कथन या वर्तमान में एसक्यूएल इंजेक्शन रोकथाम का समर्थन करने वाले किसी भी अन्य उपकरण का उपयोग करने के लिए अनुशंसित किया गया है, मान लें कि ये उपकरण अब उपलब्ध नहीं हैं? आप अपना आवेदन कैसे सुरक्षित करते हैं?

एसक्यूएल इंजेक्शन के खिलाफ मेरा दृष्टिकोण है: इसे डेटाबेस में भेजने से पहले उपयोगकर्ता इनपुट डेटा को साफ़ करना (किसी भी क्वेरी के अंदर इसका उपयोग करने से पहले)।

डेटा फ़िल्टरिंग (असुरक्षित डेटा को सुरक्षित डेटा में कनवर्ट करना) इस बात पर विचार करें कि PDO और MySQLi उपलब्ध नहीं हैं, आप अपना आवेदन कैसे सुरक्षित कर सकते हैं? क्या आप मुझे उनका उपयोग करने के लिए मजबूर करते हैं? PHP के अलावा अन्य भाषाओं के बारे में क्या? मैं सामान्य विचार प्रदान करना पसंद करता हूं क्योंकि यह विशिष्ट सीमा के लिए व्यापक सीमा के लिए उपयोग नहीं किया जा सकता है।

  1. एसक्यूएल उपयोगकर्ता (उपयोगकर्ता विशेषाधिकार सीमित): सबसे आम एसक्यूएल ऑपरेशंस (चयन, अद्यतन, INSERT) हैं, फिर, उस उपयोगकर्ता को अद्यतन विशेषाधिकार क्यों देना है जिसके लिए इसकी आवश्यकता नहीं है? उदाहरण के लिए लॉगिन, और खोज पृष्ठ केवल चयन का उपयोग कर रहे हैं, फिर, इन पृष्ठों में उच्च विशेषाधिकारों के साथ डीबी उपयोगकर्ताओं का उपयोग क्यों करें? नियम: सभी एसक्यूएल संचालन के लिए सभी विशेषाधिकारों के लिए एक डेटाबेस उपयोगकर्ता न बनाएं, आप आसानी से उपयोग के लिए उपयोगकर्ता नाम के रूप में अपनी योजना (डील्यूसर, चयनकर्ता, अद्यतनकर्ता) बना सकते हैं।

कम से कम विशेषाधिकार के सिद्धांत देखें

  1. डेटा फ़िल्टरिंग: किसी भी क्वेरी के निर्माण से पहले उपयोगकर्ता इनपुट को प्रोग्रामर के लिए मान्य और फ़िल्टर किया जाना चाहिए, प्रत्येक उपयोगकर्ता-इनपुट चर के लिए कुछ गुणों को परिभाषित करना महत्वपूर्ण है: डेटा प्रकार, डेटा पैटर्न और डेटा लंबाई । एक फ़ील्ड जो कि (x और y) के बीच एक संख्या है, एक स्ट्रिंग (टेक्स्ट) वाले फ़ील्ड के लिए सटीक नियम का उपयोग करके सटीक रूप से मान्य होना चाहिए: उदाहरण केस है, उदाहरण के लिए, उपयोगकर्ता नाम में केवल कुछ वर्ण होने चाहिए, [a- zA-Z0-9_-।] लंबाई (x और n) के बीच भिन्न होती है जहां x और n (integers, x <= n)। नियम: सटीक फ़िल्टर और सत्यापन नियम बनाना मेरे लिए सबसे अच्छा अभ्यास है।

  2. अन्य टूल्स का उपयोग करें: यहां, मैं आपसे सहमत हूं कि तैयार कथन (पैरामीट्रिज्ड क्वेरी) और संग्रहीत प्रक्रियाएं, यहां के नुकसान इन तरीकों से उन्नत कौशल की आवश्यकता है जो अधिकांश उपयोगकर्ताओं के लिए मौजूद नहीं हैं, मूलभूत विचार यहां SQL क्वेरी के बीच अंतर करना है और डेटा का उपयोग किया जा रहा है, दोनों दृष्टिकोणों का उपयोग असुरक्षित डेटा के साथ भी किया जा सकता है, क्योंकि उपयोगकर्ता-इनपुट डेटा मूल क्वेरी (जैसे कोई भी या x = x) में कुछ भी नहीं जोड़ता है। अधिक जानकारी के लिए, कृपया ओडब्ल्यूएएसपी एसक्यूएल इंजेक्शन रोकथाम धोखा शीट पढ़ें ।

अब, यदि आप एक उन्नत उपयोगकर्ता हैं, तो इस रक्षा का उपयोग अपनी पसंद के अनुसार शुरू करें, लेकिन शुरुआती लोगों के लिए, यदि वे संग्रहीत प्रक्रिया को जल्दी से कार्यान्वित नहीं कर सकते हैं और कथन तैयार कर सकते हैं, तो इनपुट डेटा को जितना संभव हो उतना फ़िल्टर करना बेहतर होगा।

अंत में, मान लें कि उपयोगकर्ता अपना उपयोगकर्ता नाम दर्ज करने के बजाय नीचे इस पाठ को भेजता है:

[1] UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = 'root'

इस इनपुट को किसी भी तैयार कथन और संग्रहित प्रक्रियाओं के बिना जल्दी से चेक किया जा सकता है, लेकिन सुरक्षित पक्ष पर रहने के लिए, उनका उपयोग करके उपयोगकर्ता-डेटा फ़िल्टरिंग और सत्यापन के बाद शुरू होता है।

अंतिम बिंदु अप्रत्याशित व्यवहार का पता लगा रहा है जिसके लिए अधिक प्रयास और जटिलता की आवश्यकता है; सामान्य वेब अनुप्रयोगों के लिए इसकी अनुशंसा नहीं की जाती है। उपरोक्त उपयोगकर्ता इनपुट में अप्रत्याशित व्यवहार चयन, यूनियन, आईएफ, सबस्ट्रिंग, बेंचमार्क, एसएचए, रूट इन शब्दों के एक बार पता चला है, आप इनपुट से बच सकते हैं।

Update1:

एक उपयोगकर्ता ने टिप्पणी की कि यह पोस्ट बेकार है, ठीक है! यहां दिया गया है OWASP.ORG क्या प्रदान किया गया है:

प्राथमिक सुरक्षा:

विकल्प # 1: तैयार वक्तव्यों का उपयोग (पैरामीटरेटेड क्वेरीज़)
विकल्प # 2: संग्रहीत प्रक्रियाओं का उपयोग
विकल्प # 3: सभी उपयोगकर्ता समर्थित इनपुट से बचें

अतिरिक्त सुरक्षा:

भी लागू करें: कम विशेषाधिकार
भी प्रदर्शन करें: व्हाइट सूची इनपुट सत्यापन

जैसा कि आप जानते हैं, किसी लेख पर दावा करना वैध तर्क द्वारा समर्थित होना चाहिए, कम से कम एक संदर्भ! अन्यथा, इसे हमले और बुरे दावे के रूप में माना जाता है!

Update2:

PHP मैनुअल से, PHP: तैयार वक्तव्य - मैनुअल :

भागने और एसक्यूएल इंजेक्शन

बाउंड चर सर्वर से स्वचालित रूप से बच जाएगा। सर्वर निष्पादन से पहले बयान टेम्पलेट में उचित स्थानों पर अपने बच निकले मूल्यों को सम्मिलित करता है। उपयुक्त रूपांतरण बनाने के लिए, बाध्य चर के प्रकार के लिए सर्वर को एक संकेत प्रदान किया जाना चाहिए। अधिक जानकारी के लिए mysqli_stmt_bind_param () फ़ंक्शन देखें।

एसक्यूएल इंजेक्शन को रोकने के लिए सर्वर के भीतर मूल्यों के स्वचालित भागने को कभी-कभी सुरक्षा सुविधा माना जाता है। अगर इनपुट मूल्य सही ढंग से बच निकले हैं तो गैर-तैयार बयान के साथ सुरक्षा की एक ही डिग्री हासिल की जा सकती है।

Update3:

मैंने तैयार बयान का उपयोग करते समय पीडीओ और MySQLi क्वेरी को MySQL सर्वर पर क्वेरी भेजने के लिए परीक्षण मामलों का निर्माण किया:

पीडीओ:

$user = "''1''"; //Malicious keyword
$sql = 'SELECT * FROM awa_user WHERE userame =:username';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':username' => $user));

क्वेरी लॉग:

    189 Query SELECT * FROM awa_user WHERE userame ='\'\'1\'\''
    189 Quit

MySQLi:

$stmt = $mysqli->prepare("SELECT * FROM awa_user WHERE username =?")) {
$stmt->bind_param("s", $user);
$user = "''1''";
$stmt->execute();

क्वेरी लॉग:

    188 Prepare   SELECT * FROM awa_user WHERE username =?
    188 Execute   SELECT * FROM awa_user WHERE username ='\'\'1\'\''
    188 Quit

यह स्पष्ट है कि एक तैयार कथन भी डेटा से बच रहा है, और कुछ नहीं।

जैसा कि उपर्युक्त कथन में भी उल्लेख किया गया है The automatic escaping of values within the server is sometimes considered a security feature to prevent SQL injection. The same degree of security can be achieved with non-prepared statements, if input values are escaped correctly, इसलिए, यह साबित करता है कि intval()क्वेरी सत्यापन भेजने से पहले डेटा सत्यापन को पूर्णांक मानों के लिए एक अच्छा विचार है, इसके अलावा, क्वेरी भेजने से पहले दुर्भावनापूर्ण उपयोगकर्ता डेटा को रोकना सही और मान्य दृष्टिकोण है

कृपया अधिक जानकारी के लिए यह प्रश्न देखें: पीडीओ MySQL को कच्ची क्वेरी भेजता है जबकि माईस्क्ली तैयार क्वेरी भेजता है, दोनों एक ही परिणाम उत्पन्न करते हैं

संदर्भ:

  1. एसक्यूएल इंजेक्शन धोखा शीट
  2. एसक्यूएल इंजेक्षन
  3. सूचना सुरक्षा
  4. सुरक्षा सिद्धांत
  5. डेटा मान्य

इस समस्या का सरल विकल्प डेटाबेस में उचित अनुमति देकर हल किया जा सकता है। उदाहरण के लिए: यदि आप एक MySQL डेटाबेस का उपयोग कर रहे हैं तो टर्मिनल या यूआई के माध्यम से डेटाबेस में प्रवेश करें और बस इस कमांड का पालन करें:

 GRANT SELECT, INSERT, DELETE ON database TO [email protected]'localhost' IDENTIFIED BY 'password';

यह उपयोगकर्ता को केवल निर्दिष्ट क्वेरी के साथ ही सीमित होने तक सीमित कर देगा। हटाए गए अनुमति को हटाएं और इसलिए php पेज से निकाली गई क्वेरी से डेटा कभी भी हटा नहीं जाएगा। दूसरी बात यह है कि विशेषाधिकारों को फ्लश करना ताकि mysql अनुमतियों और अपडेट को रीफ्रेश कर सके।

FLUSH PRIVILEGES; 

flush बारे में अधिक जानकारी ।

उपयोगकर्ता के लिए मौजूदा विशेषाधिकार देखने के लिए निम्न क्वेरी को आग लगाना है।

select * from mysql.user where User='username';

GRANT बारे में और जानें ।


मैंने कई सालों पहले इस छोटे से काम को लिखा है:

function sqlvprintf($query, $args)
{
    global $DB_LINK;
    $ctr = 0;
    ensureConnection(); // Connect to database if not connected already.
    $values = array();
    foreach ($args as $value)
    {
        if (is_string($value))
        {
            $value = "'" . mysqli_real_escape_string($DB_LINK, $value) . "'";
        }
        else if (is_null($value))
        {
            $value = 'NULL';
        }
        else if (!is_int($value) && !is_float($value))
        {
            die('Only numeric, string, array and NULL arguments allowed in a query. Argument '.($ctr+1).' is not a basic type, it\'s type is '. gettype($value). '.');
        }
        $values[] = $value;
        $ctr++;
    }
    $query = preg_replace_callback(
        '/{(\\d+)}/', 
        function($match) use ($values)
        {
            if (isset($values[$match[1]]))
            {
                return $values[$match[1]];
            }
            else
            {
                return $match[0];
            }
        },
        $query
    );
    return $query;
}

function runEscapedQuery($preparedQuery /*, ...*/)
{
    $params = array_slice(func_get_args(), 1);
    $results = runQuery(sqlvprintf($preparedQuery, $params)); // Run query and fetch results.   
    return $results;
}

यह एक लाइनर सी # -श स्ट्रिंग में चल रहे बयान की अनुमति देता है। जैसे:

runEscapedQuery("INSERT INTO Whatever (id, foo, bar) VALUES ({0}, {1}, {2})", $numericVar, $stringVar1, $stringVar2);

यह परिवर्तनीय प्रकार पर विचार से बच निकलता है। यदि आप टेबल, कॉलम नाम को पैरामीटर करने का प्रयास करते हैं, तो यह असफल हो जाएगा क्योंकि यह प्रत्येक स्ट्रिंग को उद्धरणों में रखता है जो एक अमान्य वाक्यविन्यास है।

सुरक्षा अद्यतन: पिछले str_replaceसंस्करण में उपयोगकर्ता डेटा में {#} टोकन जोड़कर इंजेक्शन की अनुमति है। preg_replace_callbackयदि प्रतिस्थापन में इन टोकन शामिल हैं तो यह संस्करण समस्याएं नहीं पैदा करता है।


एक आसान तरीका CodeIgniter या Laravel जैसे PHP ढांचे का उपयोग करना होगा जिसमें फ़िल्टरिंग और सक्रिय रिकॉर्ड जैसी अंतर्निहित सुविधाएं हों ताकि आपको इन बारीकियों के बारे में चिंता न करें।


जो कुछ भी आप समाप्त करते हैं, सुनिश्चित करें कि आप अपने इनपुट की जांच कर चुके हैं, पहले से ही magic_quotes या किसी अन्य अच्छी तरह से कचरा नहीं है, और यदि आवश्यक हो, तो इसे stripslashes माध्यम से चलाएं या जो भी इसे स्वच्छ करना है।


पैरामीटरेटेड क्वेरी और इनपुट सत्यापन जाने का तरीका है। ऐसे कई परिदृश्य हैं जिनके अंतर्गत SQL इंजेक्शन हो सकता है, भले ही mysql_real_escape_string() का उपयोग किया गया हो।

वे उदाहरण एसक्यूएल इंजेक्शन के लिए कमजोर हैं:

$offset = isset($_GET['o']) ? $_GET['o'] : 0;
$offset = mysql_real_escape_string($offset);
RunQuery("SELECT userid, username FROM sql_injection_test LIMIT $offset, 10");

या

$order = isset($_GET['o']) ? $_GET['o'] : 'userid';
$order = mysql_real_escape_string($order);
RunQuery("SELECT userid, username FROM sql_injection_test ORDER BY `$order`");

दोनों मामलों में, आप ' encapsulation की रक्षा के लिए ' का उपयोग नहीं कर सकते हैं।

Source : अप्रत्याशित एसक्यूएल इंजेक्शन (जब भागना पर्याप्त नहीं है)


मैं एहसान संग्रहित प्रक्रियाओं ( MySQL 5.0 के बाद से संग्रहित प्रक्रियाओं का समर्थन किया गया है ) को देखने के एक सुरक्षा बिंदु से - फायदे हैं -

  1. अधिकांश डेटाबेस ( MySQL समेत ) संग्रहीत प्रक्रियाओं को निष्पादित करने के लिए उपयोगकर्ता पहुंच को प्रतिबंधित करने में सक्षम बनाता है। बढ़िया सुरक्षा पहुंच नियंत्रण विशेषाधिकारों के हमलों की वृद्धि को रोकने के लिए उपयोगी है। यह समझौता किए गए अनुप्रयोगों को डेटाबेस के विरुद्ध सीधे SQL चलाने में सक्षम होने से रोकता है।
  2. वे अनुप्रयोग से कच्चे एसक्यूएल क्वेरी को सारणी देते हैं ताकि डेटाबेस संरचना की कम जानकारी एप्लिकेशन के लिए उपलब्ध हो। यह लोगों के डेटाबेस की अंतर्निहित संरचना को समझने और उपयुक्त हमलों को डिजाइन करने के लिए कठिन बनाता है।
  3. वे केवल पैरामीटर स्वीकार करते हैं, इसलिए पैरामीटरयुक्त प्रश्नों के फायदे हैं। बेशक - आईएमओ आपको अभी भी अपने इनपुट को स्वच्छ करने की आवश्यकता है - खासकर अगर आप संग्रहीत प्रक्रिया के अंदर गतिशील एसक्यूएल का उपयोग कर रहे हैं।

नुकसान हैं -

  1. वे (संग्रहीत प्रक्रियाओं) को बनाए रखने के लिए कठिन हैं और बहुत तेज़ी से गुणा करते हैं। इससे उन्हें एक मुद्दा मिल जाता है।
  2. वे गतिशील प्रश्नों के लिए बहुत उपयुक्त नहीं हैं - यदि वे पैरामीटर के रूप में गतिशील कोड स्वीकार करने के लिए बनाए गए हैं तो बहुत से फायदे अस्वीकार कर दिए जाते हैं।

** चेतावनी: इस उत्तर में वर्णित दृष्टिकोण केवल बहुत विशिष्ट परिदृश्यों पर लागू होता है और यह सुरक्षित नहीं है क्योंकि एसक्यूएल इंजेक्शन हमले न केवल इंजेक्ट करने में सक्षम होने पर भरोसा करते हैं X=Y। **

यदि हमलावर PHP के $_GETचर के माध्यम से या यूआरएल की क्वेरी स्ट्रिंग के माध्यम से फ़ॉर्म में हैक करने की कोशिश कर रहे हैं , तो वे सुरक्षित नहीं होने पर उन्हें पकड़ सकेंगे।

RewriteCond %{QUERY_STRING} ([0-9]+)=([0-9]+)
RewriteRule ^(.*) ^/track.php

क्योंकि 1=1, 2=2, 1=2, 2=1, 1+1=2, आदि ... एक हमलावर की एक SQL डेटाबेस के लिए आम सवाल कर रहे हैं। शायद यह कई हैकिंग अनुप्रयोगों द्वारा भी प्रयोग किया जाता है।

लेकिन आपको सावधान रहना चाहिए, कि आपको अपनी साइट से एक सुरक्षित क्वेरी को फिर से लिखना नहीं चाहिए। ऊपर दिया गया कोड आपको फिर से लिखने या रीडायरेक्ट करने के लिए एक टिप दे रहा है (यह आपके ऊपर निर्भर करता है) कि एक पृष्ठ में हैकिंग-विशिष्ट डायनामिक क्वेरी स्ट्रिंग जो हमलावर के आईपी ​​पते को स्टोर करेगी , या फिर उनकी कुकीज, इतिहास, ब्राउज़र या किसी भी अन्य संवेदनशील जानकारी, ताकि आप बाद में अपने खाते पर प्रतिबंध लगाकर या अधिकारियों से संपर्क कर सकें।


दूसरी तरफ व्युत्पन्न तालिका का उपयोग करना है:

UPDATE t
SET t.col1 = a.col1
    ,t.col2 = a.col2
FROM (
SELECT id, col1, col2 FROM @tbl2) a
INNER JOIN @tbl1 t ON t.id = a.id

नमूना डेटा

DECLARE @tbl1 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))
DECLARE @tbl2 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))

INSERT @tbl1 SELECT 1, 'a', 'b' UNION SELECT 2, 'b', 'c'

INSERT @tbl2 SELECT 1, '1', '2' UNION SELECT 2, '3', '4'

UPDATE t
SET t.col1 = a.col1
    ,t.col2 = a.col2
FROM (
SELECT id, col1, col2 FROM @tbl2) a
INNER JOIN @tbl1 t ON t.id = a.id

SELECT * FROM @tbl1
SELECT * FROM @tbl2






php mysql sql security sql-injection