簡體   English   中英

'<-在mysql文本中不會插入數據庫

[英]' <— in mysql text don't get inserted in database

您好,我是一個初學者,所以請至少嘗試給我一個提示,例如。

  • 英語不是我的主要語言,所以請忍受。

如果有人輸入" Hello my name is J'hon ' ,則不會在數據庫中插入文本,但是如果他輸入" Hello my name is J'hon ''Hello my name is jhon'會輸入。

好的,所以我遇到的問題是,如果有人輸入

'Hello my name is J[color=#FF0000]'[/color]hon J'onz. ' 'Hello my name is J[color=#FF0000]'[/color]hon J'onz. '未插入數據庫中。

這是腳本:

mysqli_query($DB_H, "INSERT INTO tickets (name, continutscurt, continut,type,status) VALUES ('".$_SESSION['username']."', '".$_POST['titlu']."', '".$_POST['continut']."', $numar, 0)");

在處理任何類型的用戶輸入時,您實際上應該使用准備好的語句。 如果出於某種奇怪的原因而不使用准備好的語句,請查看函數mysqli::real_escape_string 這將處理特殊字符,例如' ,這可能會破壞SQL。

使用准備好的語句,您的代碼將如下所示

if ($stmt = $DB_H->prepare("INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES (?, ?, ?, ?, ?)")) {
    $stmt->bind_param("ssssi", $_SESSION['username'], $_POST['titlu'], $_POST['continut'], $numar, 0);
    $stmt->execute();
    $stmt->close();
} else {
    echo mysqli_error($DB_H);
}

但是,如果您想使用mysqli::real_escape_string ,則需要將SESSION和POST綁定到變量中,而不是在其中插入,就像這樣(您也可以直接在查詢中這樣做,但這會使代碼更簡潔) 。

$username = mysqli_real_escape_string ($DB_H, $_SESSION['username']); 
$titlu = mysqli_real_escape_string ($DB_H, $_POST['titlu']); 
$continut = mysqli_real_escape_string ($DB_H, $_POST['continut']); 
$numar = mysqli_real_escape_string ($DB_H, $numar);

if (!mysqli_query($DB_H, "INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES ('$username', '$titlu', '$continut', '$numar', 0")) { 
    echo mysqli_error($DB_H); 
}

我還在namestatustype周圍加上了反引號`,因為這些是SQL中的關鍵字。 嚴格來說,這不是必需的,但是對於被列為保留詞或關鍵字的單詞,以及在此關鍵字列表上的更多信息, 是一個很好的做法。


您不應該將查詢成功視為理所當然,因此我在查詢周圍添加了if -block。 除非在生產/開發中,否則不應顯示錯誤。

參考文獻:

問題是SQL注入。

SQL文本中包含潛在的不安全值。

要看到這一點,請對代碼進行一點分解。

  $sql = "INSERT INTO tickets ...'" . $val . "' ... ";
  echo $sql; 

echo是一種查看發生情況的方式,您可以檢查包含SQL文本的字符串的內容。 然后將該字符串帶給另一個客戶端,並對其進行測試。 您將看到問題所在。

   ... VALUES ( ..., 'J'onz. ', ...

無效。 單引號將字符串結尾,因此字符串只是“ J”,下一部分,MySQL將嘗試解釋為SQL的一部分,而不是字符串值。 (這是一個邪惡的漏洞。巧妙地構造了字符串,並對應用程序和數據庫造成了嚴重破壞。)

解決問題的一種方法是清理值,以便可以安全地包含它們。

   ... VALUES ( ..., 'J\'onz. ', ...
                       ^^

   ... VALUES ( ..., 'J''onz. ', ...
                       ^^ 

作為一個簡單的演示,請嘗試以下查詢:

 SELECT 'J\'onz. '
 SELECT 'J''onz. '
 SELECT 'J'onz. '

(前兩個將返回您期望的字符串,第三個將導致錯誤。)

得出的結論是,需要適當地轉義要包含在SQL語句文本中的潛在不安全值。 幸運的是,MySQL客戶端庫包含mysqli_real_escape_string函數。 可以通過該函數運行可能包含單引號字符的變量,並且該函數的返回結果可以包含在SQL文本中。

  $sql = "INSERT INTO tickets ...'" 
         . mysqli_real_escape_string($DB_H,$val)
         . "' ... ";

再次,回顯$sql ,您可以看到一個單引號已被轉義,方法是在其前面加上反斜杠字符,或者將其替換為兩個sinqle引號。


有一個比“轉義”字符串更好的模式。 那就是使用帶有綁定占位符的 准備好的語句

SQL文本可以是靜態字符串:

$sql = 'INSERT INTO mytable (mycol) VALUES ( ? )' 

然后,您msyqli_prepare該語句。

然后通過調用mysqli_bind_param為占位符提供值。

然后調用mysqli_execute

使用這種模式,我們無需費心運行“轉義字符串”功能來清理輸入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM