简体   繁体   English

使用PHP函数在SQL查询中清理HTML

[英]Sanitize HTML in SQL query with PHP function

So I have a PHP page with a drop down form that when an option is selected, it uses an AJAX script to query a result from the same MySQL table. 因此,我有一个带有下拉表单的PHP页面,当选择一个选项时,它使用AJAX脚本从同一MySQL表中查询结果。 For the most part, it works like expected. 在大多数情况下,它的工作方式与预期的一样。 However, some results (specifically, options that have " or ' in the name) are not being set properly to the variable for the AJAX/GET script. Here is my main PHP script: 但是,某些结果(特别是名称中带有“或”的选项)未正确设置为AJAX / GET脚本的变量。这是我的主要PHP脚本:

<html>
 <head>
  <link rel="stylesheet" type="text/css" href="css/styles.css" media="screen" />
  <title>Add Inventory</title>
  <script>
function showUser(str)
{
if (str=="")
  {
  document.getElementById("txtHint").innerHTML="";
  return;
  } 
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","getsku.php?q="+str,true);
xmlhttp.send();
}
</script>
 </head>
 <body>
<?php
session_start();

require_once('includes/config.inc.php');
require_once('includes/functions.inc.php');

// Check login status -- if not logged in, redirect to login screen
if (check_login_status() == false) {
  redirect('login.php');
}
$thisPage='add';
include('includes/navbar.inc.php');
?>

<h1>Add New Inventory Record</h1>
<form method="POST" action="submitadd.php" />

<table id="add">

<tr>
<td class="headings"><b>Species:</b></td>
<td><select name="species:" onchange="showUser(this.value)">
      <option value="select">Choose a Species</option>
      <?php
      $prodquery="SELECT name FROM products ORDER BY name ASC";
      $result=mysqli_query($con,$prodquery) or die(mysqli_error($con));
      while ($row = mysqli_fetch_array($result)) {
        echo "<option value='" . $row['name'] . "'>" . $row['name'] . "</option>";
      }
      ?>
    </select>
</td>
</tr>

<div id='txtHint' />

<tr>
<td class="headings"><b>Fry Count:</b></td>
<td><input type="text" name="frycount" value="<?php echo $row['quantityfry']; ?>" size="35" maxlength="4" /></td>
</tr>

<tr>
<td class="headings"><b>Juvie Count:</b></td>
<td><input type="text" name="juviecount" value="<?php echo $row['quantityjuv']; ?>" size="35" maxlength="4" /></td>
</tr>

<tr>
<td class="headings"><b>Adult Count:</b></td>
<td><input type="text" name="adultcount" value="<?php echo $row['quantityadult']; ?>" size="35" maxlength="4" /></td>
</tr>

<tr>
<td class="headings"><b>Notes:</b></td>
<td><input type="text" name="notes" value="<?php echo $row['notes']; ?>" size="35" maxlength="255" /></td>
</tr>

<tr>
<td class="headings"><b>Location:</b></td>
<td><select name="location">
  <?php
  $options = set_and_enum_values($con, 'inventory', 'location');
  foreach($options as $option):
?>
    <option><?php echo $option ?></option>
<?php endforeach; ?>
</select></td>
</tr>

<tr>
<td class="headings"><b>Owner:</b></td>
<td><select name="owner">
<?php
  $options = set_and_enum_values($con, 'inventory', 'owner');
  foreach($options as $option):
?>
    <option><?php echo $option ?></option>
<?php endforeach; ?>
</select></td>
</tr>

</table>
<br />
<input type="submit" name="submit" value="submit" class="button1" />
</form>

</body>
</html>

And here is getsku.php, which is called by the AJAX script: 这是getsku.php,由AJAX脚本调用:

<?php
$q = html_entity_decode($_GET['q']);

require_once('includes/config.inc.php');

$sql="SELECT sku FROM products WHERE name = '".$q."'";

$result = mysqli_query($con,$sql);

while($row = mysqli_fetch_array($result))
  {
  echo "<td><input type='hidden' name='sku' value='" . $row['sku'] . "' readonly='readonly' size='35' /></td>";
  }

mysqli_close($con);
?>

I've been doing some testing in Firebug and here is a specific example. 我一直在Firebug中进行一些测试,这是一个特定的示例。 The row of data is: name = Lethrinops albus "Kande Island" sku = HAP002 数据行是: name = Lethrinops albus "Kande Island" sku = HAP002 name = Lethrinops albus "Kande Island" sku = HAP002

There is other data, but not of a concern for this. 还有其他数据,但与此无关。 So when the dropdown selects Lethrinops albus "Kande Island" , I want HAP002 set to a hidden field and passed to the submit button on this form. 因此,当下拉列表选择Lethrinops albus "Kande Island" ,我希望将HAP002设置为隐藏字段并传递到此表单上的HAP002按钮。 Using Firebug, I can see this under Params: q Lethrinops albus "Kande Island" 使用Firebug,我可以在Params下看到它: q Lethrinops albus "Kande Island"

Which is correct. 哪个是对的。 Here is another row of data: name = Cynotilapia afra "Lion's Cove" sku = MBN002 这是另一行数据: name = Cynotilapia afra "Lion's Cove" sku = MBN002

But within Firebug, I see this under Params: q Cynotilapia afra "Lion 但是在Firebug中,我在Params下看到了这一点: q Cynotilapia afra "Lion

Which is not correct. 这是不正确的。 I'm assuming I need to sanitize the HTML result, and I found a function that may help: 我假设我需要清理HTML结果,并且发现了一个可能会有所帮助的函数:

function htmlsan($htmlsanitize){
return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}

But I'm not sure if this is what I need, and how to use it. 但是我不确定这是否是我需要的以及如何使用它。 Can anyone point me in the right direction please? 谁能指出我正确的方向?

First of all, you should never construct an SQL query this way: 首先,永远不要以这种方式构造SQL查询:

$q = html_entity_decode($_GET['q']);
$sql="SELECT sku FROM products WHERE name = '".$q."'";

It's not a good practice, and there are security issues like SQL Injection 这不是一个好习惯,并且存在诸如SQL Injection之类的安全问题
To solve all your sanitations problems (and many others) I recommend you to use PHP Data Objects (PDO) to all your SQL connections. 为了解决您所有的卫生问题(以及许多其他问题),我建议您对所有SQL连接使用PHP数据对象(PDO)
Especially take a look at this answer How can I prevent SQL injection in PHP? 尤其是看看这个答案如何防止PHP中的SQL注入?
Use this function mysql-real-escape-string.php to sanitize you input data in MySQL query. 使用此函数mysql-real-escape-string.php清理您在MySQL查询中输入的数据。

[EDITED] Answer your question. [编辑]回答您的问题。
The problem is not in your SQL query . 问题不在您的SQL查询中 It is at <option value='problem is here!'> . 它位于<option value='problem is here!'>

You should use htmlentities to correctly escape the single-quote when name = Cynotilapia afra "Lion's Cove" . name = Cynotilapia afra "Lion's Cove"时,应使用htmlentities正确转义单引号。

echo "<option value='" . htmlentities($row['name']) . "'>" . $row['name'] . "</option>";

You may need to use html_entity_decode to decode (the reverse operation) in getsku.php. 您可能需要使用html_entity_decode解码(反向操作)的getsku.php。

Since you're passing data via GET you need to urlencode() the strings to pass them to the next page. 由于您是通过GET传递数据,因此需要urlencode()字符串才能将它们传递到下一页。 Do not decode them in the next script. 不要在下一个脚本中对其进行解码。 The superglobals are already decoded. 超全局变量已被解码。

Once you're in the next script you should use your DB extension's escape functions to use the $_GET param in your SQL query. 进入下一个脚本后,应使用数据库扩展的转义函数在SQL查询中使用$_GET参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM