Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用JS执行MySQL查询及其涉及的安全问题_Javascript_Php_Mysql_Security - Fatal编程技术网

Javascript 使用JS执行MySQL查询及其涉及的安全问题

Javascript 使用JS执行MySQL查询及其涉及的安全问题,javascript,php,mysql,security,Javascript,Php,Mysql,Security,我一直在互联网上寻找一种用JavaScript定义查询的方法,将该查询传递给PHP。让PHP建立一个MySQL连接,执行查询并返回json编码的结果 然而,我担心的是这个方法的安全性,因为用户可能会篡改查询,做你不想让他们做的事情,或者请求你不想让他们看到的数据 问题: 在这样的应用程序/插件中,您建议采取什么样的安全措施来防止用户请求我不希望他们请求的信息 编辑 我的插件的最终结果是 var data = Querier({ table: "mytable", columns:

我一直在互联网上寻找一种用JavaScript定义查询的方法,将该查询传递给PHP。让PHP建立一个MySQL连接,执行查询并返回json编码的结果

然而,我担心的是这个方法的安全性,因为用户可能会篡改查询,做你不想让他们做的事情,或者请求你不想让他们看到的数据

问题: 在这样的应用程序/插件中,您建议采取什么样的安全措施来防止用户请求我不希望他们请求的信息

编辑 我的插件的最终结果是

var data = Querier({
    table: "mytable",
    columns: {"column1", "column2", "column3"},
    where: "column2='blablabla'",
    limit: "10"
});

我将让该函数发出一个AJAX请求,并使用上述数据在PHP中执行一个查询。我想知道这会带来什么安全风险,以及如何预防这些风险。

您的问题不清楚您是否允许用户键入将针对您的数据库运行的查询,或者您在浏览器中运行的代码是否正在这样做(例如,不是用户)

如果是用户:你必须真正信任他们,因为他们可以(也可能会)破坏你的数据库

如果是您在浏览器中运行的代码在创建它们:不要这样做。相反,让客户端代码将数据发送到服务器,并在服务器上使用完全预防措施制定查询,以防止SQL注入(参数化查询等)


重新更新:

我至少可以看到几个问题:

  • 这里有一个风险:

    where: "column2='blablabla'"
    
    现在,假设我决定在它被发送到服务器并更改为:

    where: "column2=');DROP TABLE Stuff; --"
    
    http://xkcd.com/327/“>

    您无法向服务器发送完整的
    WHERE
    子句,因为您不能信任它。这就是参数化查询的要点:

    相反,请按名称指定列,并在PHP端确保正确处理参数值()

    现在,您可以在不盲目信任客户端文本的情况下构建查询;您需要对列名、运算符等进行彻底验证

  • 向全世界公开有关您的计划的信息就是免费放弃信息。安全性是一个洋葱头,洋葱头的外层之一是隐蔽性。它本身远远不够,但它是一个起点。因此,不要让您的客户机代码(因此也不要让任何人阅读它)了解您的表名和列名。考虑使用服务器端名称映射等。


  • 取决于你打算怎么做,你可能会有一个比这个经济体中的洞更大的洞,或者根本没有洞

    如果要在客户端编写查询并发送到php,我将创建一个用户,该用户只有
    select
    insert
    delete
    update
    ,没有访问任何其他数据库的权限。
    如果使用SQlite,请忽略此选项。
    我劝你不要这样

    如果您在服务器端构建查询,只需将所需数据塞入服务器即可

    我会将代码更改为如下内容:

    var link = QuerierLink('sql.php');//filename to use for the query
    
    var data = Querier('users',link);//locks access to only this table
    
    data.select({
        columns: ['id','name','email'],
        where: [
            {id:{'>':5}},
            {name:{'like':'%david%'}}
        ],
        limit:10
    });
    
    在服务器端,它将生成查询:

    select `id`,`name`,`email` from `db.users` where `id`>5 and `name` like '%david%' limit 10
    
    这将是更好的使用

    对于准备好的报表,您可以使用:

    select `id`,`name`,`email` from `db.users` where `id`>:id and `name` like :name limit 10
    
    传递给PDO,伪代码:

    $query='select `id`,`name`,`email` from `'.$database_name.'.users` where `id`>:id and `name` like :name limit 10';
    $result=$PDO->exec($query,array(
             'id'=>5,
             'name'=>'%david%'
        )
    );
    
    这是首选的方式,因为您可以更好地控制传递的内容

    此外,请沿表的名称设置确切的数据库名称,以避免用户访问其他表/数据库中的内容。
    其他数据库包括
    information\u schema
    ,其中包含整个数据库中的每一条信息,包括用户列表和限制。
    对于SQlite,忽略这一点


    如果要使用MySQL/MariaDB/other,则应禁用所有读/写权限
    您真的不希望任何人将文件写入您的服务器!特别是写入他们希望的任何位置。
    风险:他们有一只新的小狗供攻击者随心所欲!这是一个巨大的洞。
    解决方案:使用或系统变量,使用
    .htaccess
    禁用或限制对阻止外部访问的目录的访问

    如果使用SQlite,只需根据模板文件为每个连接的客户端创建一个
    .SQlite(3)
    文件。然后在用户关闭连接时删除该文件,或者对于超过x时间的文件,每n分钟删除一次。
    风险:用
    .sqlite
    文件填充磁盘。
    解决方案:尽早清除文件或使用带有
    cron
    作业的ramdisk


    很久以前,我就想实现这样的想法,这是一个锻炼头脑的好方法。

    也许我会像这样实现它!

    更重要的是要小心您为MySQL用户授予此类操作的权限。

    例如,您不希望他们删除数据库,也不希望他们执行这样的请求:

      LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE test FIELDS TERMINATED BY '\n';
    
    您必须限制此MySQL用户启用的操作,以及他访问的表

    访问总数据库:

      grant select on database_name.*
          to 'user_name'@'localhost' identified by 'password';
    
    访问表:

      grant select on database_name.table_name
          to 'user_name'@'localhost' identified by 'password';
    
    然后…还有什么…这应该避免不必要的SQL注入,以更新/修改表或访问其他表/数据库,至少,只要您向该用户授予的唯一权限是“选择特定表/数据库”

    但这并不能避免用户启动一个愚蠢的性能要求,这可能需要您所有的CPU

    var data = Querier({
        table: "mytable, mytable9, mytable11, mytable12",
        columns: {"mytable.column1", "count(distinct mytable11.column2)",
              "SUM(mytable9.column3)"},
        where: "column8 IN(SELECT column7 FROM mytable2
               WHERE column4 IN(SELECT column5 FROM mytable3)) ",
        limit: "500000"
    });
    
    如果您不希望MySQL服务器可能出现故障,您必须对传递的数据进行一些检查

    引入简单的JavaScript数据访问 因此,您希望快速原型化一个非常酷的Web2.0JavaScript应用程序,但不想花费所有时间编写连接代码来访问数据库?传统上,要从数据库到前端获取数据,您需要
    var data = Querier({
        table: "mytable, mytable9, mytable11, mytable12",
        columns: {"mytable.column1", "count(distinct mytable11.column2)",
              "SUM(mytable9.column3)"},
        where: "column8 IN(SELECT column7 FROM mytable2
               WHERE column4 IN(SELECT column5 FROM mytable3)) ",
        limit: "500000"
    });
    
    // Sample functions to update authors
    function updateAuthorsTable() {
        dbw.getAll( function(data) {
            $('#authors').html('<table id="authors"><tr><td>ID</td><td>Author</td></tr></table>');
            $(data).each( function( ind, author ) {
                $('#authors tr:last').after('<tr><td>'+author.id+'</td><td>'+author.name+'</td></tr>');
            });
        });
    }
    
    $(document).ready(function() {
        dbw = new DbWrapper();
        dbw.table = 'authors';
    
        updateAuthorsTable();
    
        $('#addbutton').click( function() {
            dbw.insertObject( { name: $('#authorname').val() },
            function(data) {
                updateAuthorsTable();
            });
        });
    });