0

我正在尝试构建一种强大、简单、安全、包罗万象的方法来通过 ajax 将动态 SQL 查询传递给 php 脚本。我认为我还没有想出获胜者,但我现在所拥有的似乎对我的应用程序有用。我希望我的 Web 服务器上只有一个 php 脚本,它接受输入变量来构建 SQL 查询、执行查询并将结果返回到网站。执行查询并返回结果不是问题。问题是将这些输入变量传递给脚本的正确且安全的方法。

我遇到的最大困惑是如何生成 WHERE 子句仍然能够解释所有可能的不同 WHERE 子句。

假设服务器上的 PHP 文件名为master.php.

从 Javascirpt 我有这个:

$.ajax({
  type: "POST",
  url: "master.php",
  dataType: "xml",
  data: { 
      schema: "the_schema", 
      table: "the_table",
      select: JSON.stringify(['col_name_1','col_name_2','...']),
      where: JSON.stringify(["status","!=","Some Status","and","STR_TO_DATE(date,","%m/%d/%Y",")",">","(date(now())","-","INTERVAL","30","day)"])
  },
  success: function (data){
      alert(data);
      // of course here I will actually do something with the data, this is just for illustration of how the data is returned to the web page.
  }
});

data变量将是来自数据库的 XML 数据,字符串为:“failure: error msg”。

master.php服务器上的脚本中,我有这个:

<?php
    include '/config_file.php'; //checks user permissions and establishes mysqli connection

    /*
     * Table and schema are required 
     */
    $table = $mysqli->real_escape_string($_POST['table']);
    $schema = $mysqli->real_escape_string($_POST['schema']);

    /*
     * Select section
     * if there is no select then just use *
     */
    if (isset($_POST['select'])){
        $select_string = 'select ';
        $select = json_decode($_POST['select']);
        foreach($select as $key => $value){
            $select_string .= '`'.$mysqli->real_escape_string($value).'`, ';
        }
    }else{
        $select_string = 'select * ';
    }

    /*
     * Where section
     */
    if (isset($_POST['where'])){
        $where = json_decode($_POST['where']);
    }

    if (isset($where)){
        $where_string = ' where ';
        foreach ($where as $key => $value){
            if (strpos($value, ' ') !== false or strpos($value, '%') !== false){
                // if there is a space or % in the value, it must be a string so enclose it in quotes
                $where_string .= '"'.$mysqli->real_escape_string($value).'" ';
            }else{
                $where_string .= $mysqli->real_escape_string($value).' ';
            }
        }
        $where_string = rtrim($where_string);
    }

    if(!isset($where_string)) $where_string = '';

    /*
     * End of Where Section
     */


    /*
     * Build SQL
     */
    $SQL = $select_string.'from '.$schema.'.'.$table.$where_string;

    //...continue to execute query and echo results
?>

如您所见,where数组的每个部分都被转义并添加到查询中,甚至列名和运算符(=、!=、>、< 等)。

另外,正如您所看到的,它们似乎有点疯狂,我为 where 子句的这一部分的每个部分传递了单独的字符串->and STR_TO_DATE(date, "%m/%d/%Y" ) > (date(now()) - INTERVAL 30 day)

如果你们都有

  1. 将动态 where 子句传递给 ajax 脚本的经验
  2. 如果你有更好的主意
  3. 查看脚本中的安全漏洞

请告诉我。希望我们能得到一个很好的、通用的数据基础脚本。

谢谢!

4

1 回答 1

1

我个人不推荐这种在 javascript 中公开数据库列名的方法,这是完全危险的。

简单的例子是您可以在浏览器级别操作 ajax 参数并针对您的数据库执行它。您只是使黑客能够获取有关您的数据的更多信息。

例如,我可以停止 where close 以便我可以通过执行不带 where 参数的调用来查看数据库中的所有数据。如果您想开发这样的动态查询,请确保您在 ajax 传递的参数和真实表列之间使用了一些映射,以便这些列不会直接暴露给黑客。

这就是我可以在这个脚本中看到的基本安全问题。

希望这可以帮助。

谢谢。

于 2012-08-17T09:30:05.877 回答