如何使这个PHP代码段访问SQL安全?

时间:2014-05-21 07:54:01

标签: php sql oracle security

问题

我在目前正在建立的网站中有以下代码段。我知道由于SQL注入等原因它不安全但是解决这个问题的正确方法是什么?我看到相关的问题问同样的事情,但使用MySQL,并且有PDO,但是PDO_OCI是实验性的,所以我不想使用它。

我还有其他选择吗?我是否只创建一个函数来剥离某些字符并将其包裹在$_POST周围,如str_replace(';', '', $_POST['username']);

下面的代码段是网站中唯一实际接受用户输入$_POST的部分,在查询中,所以我只需要确保下面的内容正确无误。

代码

<?php

if (!empty($_POST)) {

  $stid = oci_parse($conn, "SELECT CustomerNo FROM Customers WHERE Username = '" . $_POST['username'] . "' AND Password = '" . $_POST['password'] . "'");
  oci_execute($stid);

  $row = oci_fetch_array($stid, OCI_NUM);
  if (!empty($row['0'])) {

    session_start();
    $_SESSION['customer'] = $row['0'];
    $_SESSION['username'] = $_POST['username'];

  }

  oci_free_statement($stid);
  oci_close($conn);

}

?>

1 个答案:

答案 0 :(得分:1)

快速Google search for "php oci parameter"产生了oci_bind_by_name function,看起来它可用于创建参数化查询(即The Right Way™)。

从该页面上的示例推断,您很可能将代码更改为(未经测试,但最有可能是正确的):

<?php

if (!empty($_POST)) {

  $stid = oci_parse($conn, 'SELECT CustomerNo FROM Customers WHERE Username = :username AND Password = :password');

  oci_bind_by_name($stid, ':username', $_POST['username']);
  oci_bind_by_name($stid, ':password', $_POST['password']);

  oci_execute($stid);

  $row = oci_fetch_array($stid, OCI_NUM);
  if (!empty($row['0'])) {

    session_start();
    $_SESSION['customer'] = $row['0'];
    $_SESSION['username'] = $_POST['username'];

  }

  oci_free_statement($stid);
  oci_close($conn);

}

?>

这样,您的用户输入将永远不会与SQL语句混合。哦,我真的希望密码不是纯文本,就像它看起来......:' - (