Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

तैयार विवरण पर स्विच करना

मैं उसी स्थिति में रहा हूं। मैं संयोजित बयानों का भी उपयोग कर रहा था, फिर मैंने अपने आवेदन को तैयार बयानों में बदल दिया।

बुरी खबर क्या आप क्लाइंट डेटा को SQL स्टेटमेंट में जोड़कर बनाए गए प्रत्येक SQL स्टेटमेंट को बदलने जा रहे हैं, जो आपकी 50 स्रोत फ़ाइलों में लगभग हर SQL स्टेटमेंट होगा।

खुशखबरी उदाहरण के लिए, तैयार बयानों पर स्विच करने से होने वाला लाभ अमूल्य है:

1-आप "एसक्यूएल इंजेक्शन अटैक" नामक किसी चीज के बारे में कभी भी चिंतित नहीं होंगे

php मैनुअल कहते हैं

मेरे लिए, वह कारण-मन की शांति- मेरे स्रोत कोड को बदलने की लागत का भुगतान करने के लिए पर्याप्त है। , अब आपके ग्राहक प्रपत्र नाम फ़ील्ड में टाइप कर सकते हैं robert; DROP table students; -- ;) और आप सुरक्षित महसूस करते हैं कि कुछ नहीं होने वाला है

2- अब आपको क्लाइंट पैरामीटर से बचने की जरूरत नहीं है। आप उन्हें सीधे SQL कथन में उपयोग कर सकते हैं, कुछ इस तरह:

$query = "SELECT FROM user WHERE id = ?";
$vars[] = $_POST['id'];

के बजाय

$id = $mysqli->real_escape_string($_POST['id']);
$query = "SELECT FROM user WHERE id = $id";

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

कोड बदलना

आम तौर पर स्रोत फ़ाइलों को बदलना हमेशा जोखिम भरा होता है और इसमें दर्द होता है, खासकर यदि आपका सॉफ़्टवेयर डिज़ाइन खराब है और यदि आपके पास स्पष्ट परीक्षण योजना नहीं है। लेकिन मैं आपको बताऊंगा कि मैंने इसे यथासंभव आसान बनाने के लिए क्या किया।

मैंने एक फ़ंक्शन बनाया है जिसका उपयोग प्रत्येक डेटाबेस इंटरैक्शन कोड करने जा रहा है, ताकि आप बाद में जो चाहें उसे एक ही स्थान पर बदल सकें- वह फ़ंक्शन- आप ऐसा कुछ बना सकते हैं

class SystemModel
{
    /**
     * @param string $query
     * @param string $types
     * @param array $vars
     * @param \mysqli $conn
     * @return boolean|$stmt
     */
    public function preparedQuery($query,$types, array $vars, $conn)
    {
        if (count($vars) > 0) {
            $hasVars = true;
        }
        array_unshift($vars, $types);
        $stmt = $conn->prepare($query);
        if (! $stmt) {
            return false;
        }
        if (isset($hasVars)) {
            if (! call_user_func_array(array( $stmt, 'bind_param'), $this->refValues($vars))) {
                return false;
            }
        }
        $stmt->execute();
        return $stmt;
    }

    /* used only inside preparedQuery */
    /* code taken from: https://stackoverflow.com/a/13572647/5407848 */
    protected function refValues($arr)
    {
        if (strnatcmp(phpversion(), '5.3') >= 0) {
            $refs = array();
            foreach ($arr as $key => $value)
                $refs[$key] = &$arr[$key];
                return $refs;
        }
        return $arr;
    }
}

अब, आप अपनी स्रोत फ़ाइलों में कहीं भी इस इंटरफ़ेस का उपयोग कर सकते हैं, उदाहरण के लिए, चलिए आपके वर्तमान SQL कथनों को बदलते हैं जो आपने प्रश्न में प्रदान किए हैं। आइए इसे बदलें

$mysqli = new mysqli('localhost', "root", "", "testdb");
$addresult = "
                SELECT a.firstnames, a.surname, a.schoolrole, a.datejoined 
                FROM teachers a LEFT JOIN schools b ON a.schoolid = b.id 
                WHERE b.id = '".$inputvalues['schoolid']."'";

if( $result = $mysqli->query($addresult) ) {
    while($row = $result->fetch_all())
    {
        $returnResult = $row;
    }
}

इसमें

$mysqli = new mysqli('localhost', "root", "", "testdb");
$sysModel = new SystemModel();
$addresult = "
                SELECT a.firstnames, a.surname, a.schoolrole, a.datejoined
                FROM teachers a LEFT JOIN schools b ON a.schoolid = b.id
                WHERE b.id = ?";
$types = "i"; // for more information on paramters types, please check :
//https://php.net/manual/en/mysqli-stmt.bind-param.php
$vars = [];
$vars[] = $inputvalues['schoolid'];

$stmt = $sysModel->preparedQuery($addresult, $types, $vars, $mysqli);
if (!$stmt || $stmt->errno) {
   die('error'); // TODO: change later for a better illustrative output
}
$result = $stmt->get_result();
$returnResult = [];
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
    $returnResult[] = $row;
}

हां, एसक्यूएल इंजेक्शन अटैक खराब स्ट्रिंग को आपके एसक्यूएल स्टेटमेंट में जोड़कर लागू किया जाता है। जहां यह एक INSERT है , SELECT , DELETE , UPDATE . उदाहरण के लिए

$query = "SELECT * FROM user WHERE name = '{$_GET['name']}' AND password = '{$_GET['pass']}'"

ऐसा कुछ

. द्वारा शोषण किया जा सकता है
// exmaple.com?name=me&pass=1' OR 1=1; -- 

जिसके परिणामस्वरूप एक SQL कथन होगा

$query = "SELECT * FROM user WHERE name = 'me' AND password = '1' OR 1=1; -- '"
//executing the SQL statement and getting the result
if($result->num_rows){
    //user is authentic
}else{
    //wrong password
}
// that SQL will always get results from the table which will be considered a correct password

अपने सॉफ़्टवेयर को तैयार किए गए कथनों में बदलने के लिए शुभकामनाएँ, और याद रखें कि मन की शांति आपको यह जानने से मिलने वाली है कि जो कुछ भी होता है, आप SQL इंजेक्शन हमलों से सुरक्षित हैं, स्रोत फ़ाइलों को बदलने की लागत के लायक है




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डालने के बाद mySQL रिटर्न इंडेक्स

  2. क्या क्रॉस-टेबल इंडेक्सिंग संभव है?

  3. MySQL प्रतिकृति स्वास्थ्य जाँच स्क्रिप्ट

  4. आप खंड से अद्यतन के लिए लक्ष्य तालिका निर्दिष्ट नहीं कर सकते हैं

  5. MySQL में फुल आउटर जॉइन कैसे करें?