【问题标题】:How to prevent SQL Injection for URL Parameter changing (DELETE Statement) PHP如何防止 SQL 注入更改 URL 参数(DELETE 语句)PHP
【发布时间】:2013-04-14 08:41:22
【问题描述】:

我有一个如下代码,用于通过 URL 参数删除条目

<td><a href="deletecar.php?car_id=<?php echo $row_cars['car_id']; ?>" onclick=" if ( !confirm('Are you sure to DELETE?') ) return false; ">Delete</a></td>

这是URL参数输出

http://localhost/html/deletecar.php?car_id=17

但如果我将 car_id=17 更改为 car_id=23(在其他用户的汽车列表中),它就会删除

如何防止这种情况发生

deletecar.php 如下所示

<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  if (PHP_VERSION < 6) {
    $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
  }

  $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}
}

if ((isset($_GET['car_id'])) && ($_GET['car_id'] != "") && (isset($_SESSION['MM_Username']))) {
  $deleteSQL = sprintf("DELETE FROM cars WHERE car_id=%s",
                       GetSQLValueString($_GET['car_id'], "int"));

  mysql_select_db($database_conn, $conn);
  $Result1 = mysql_query($deleteSQL, $conn) or die(mysql_error());

  $deleteGoTo = "myaccount.php";
  if (isset($_SERVER['QUERY_STRING'])) {
    $deleteGoTo .= (strpos($deleteGoTo, '?')) ? "&" : "?";
    $deleteGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $deleteGoTo));
}
?>

这是我在数据库中的表

INSERT INTO `car` (`car_id`, `c_id`, `c_brand`, `c_model`, `c_model_nd`, `c_model_year`, `c_color`, `c_capacity`, `c_owner`, `c_statu`, `c_show`) VALUES
(16, '34DA1593', 'Volkswagen', 'Volt', '313 CDI', 2006, 'Beyaz', '', 18, 'yakamozturizm', 'Boş', 0),
(17, '34BC5897', 'Mercedes', 'Sprinter', '313CDI', 2006, 'Gri', '', 14, 'PcRestorer', 'Boş', 0),
(18, '34DBC145', 'Volkswagen', 'Volt', '213 CDI', 2013, 'Beyaz', '', 16, 'PcRestorer', 'Boş', 0);

编辑....

我已经像那样更改了我的代码

$colname_delete = "-1";
if (isset($_GET['car_id'])) {
  $colname_delete = $_GET['car_id'];
}
$owner_delete = "-1";
if (isset($_SESSION['MM_Username'])) {
  $owner_delete = $_SESSION['MM_Username'];
}

if ((isset($_GET['car_id'])) && ($_GET['car_id'] != "")) {
  $deleteSQL = sprintf("DELETE FROM minibusler  WHERE car_id = %s AND c_owner =%s", 

GetSQLValueString($colname_delete, "int"),
GetSQLValueString($owner_delete, "text"));

  mysql_select_db($database_conn, $conn);
  $Result1 = mysql_query($deleteSQL, $conn) or die(mysql_error());

  $deleteGoTo = "myaccount.php";
  if (isset($_SERVER['QUERY_STRING'])) {
    $deleteGoTo .= (strpos($deleteGoTo, '?')) ? "&" : "?";
    $deleteGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $deleteGoTo));
}

看起来很有效,您认为这样做是否安全

感谢您的帮助

【问题讨论】:

  • 这绝不是 SQL 注入。剩下的问题没问题,没有什么可否决的。
  • 第一个条件看起来没什么用

标签: php mysql sql-injection url-parameters


【解决方案1】:

让它不那么臃肿

if (empty($_SESSION['MM_Username'])) {
  exit; // take appropriate action here
}
if (empty($_GET['car_id'])) {
  exit; // take appropriate action here
}

mysql_select_db($database_conn, $conn);
$sql = sprintf("DELETE FROM minibusler  WHERE car_id = %s AND c_owner =%s", 
                GetSQLValueString($_GET['car_id'], "int"),
                GetSQLValueString($_SESSION['MM_Username'], "text"));
mysql_query($sql, $conn) or trigger_error(mysql_error());

header("Location: myaccount.php");
exit;

【讨论】:

    【解决方案2】:

    无论如何,在删除car 之前,您都应该检查它是否属于当前用户。如果没有显示合适的消息。

    【讨论】:

    • 是的,我在问最好的方法是什么
    • SELECT COUNT(*) from cars, users WHERE car.car_id=? AND car.owner=users.user_id(对于某些人来说,可能过于简单了,猜猜你的数据库结构是什么样的)
    • 不知道你的数据库的结构,我不能说太多。但基本上你应该进行查询并获取汽车的所有者 ID,并将其与当前用户的 ID 进行比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2018-08-16
    • 2012-01-05
    • 2011-05-01
    • 1970-01-01
    相关资源
    最近更新 更多