javascript - sql 注入(inject) - 如何清理程序生成的 sql 子句?

标签 javascript sql security sql-injection

在标准 Ajax 中,whereorder by SQL 子句由程序(而非用户)提供,例如

var url = ".select?dd=emp&where="+escape("emp_tp='abc' and hire_dt<current_date-'2 years' and super_emp_id is distinct from emp_id")

在服务器上回答

$where = (isset($_GET['where'])) ? pureClause($_GET['where']) : null;
$order = (isset($_GET['order'])) ? pureClause($_GET['order']) : null;
...
$query = $query.(($where)?" where $where":'').(($order)?" order by $order":'');

问题是 pureClause 函数应该是什么样子?

现在 pureClause 如果存在以下任何一项,则会引发错误:

; select insert update delete drop create truncate

如果是其他注入(inject)导致查询失败,那也没关系,只要数据没有损坏

对我来说这似乎足够了,但在我心里,我知道我错了。

说明:

  • 在 Postgres 中准备好的语句虽然速度非常快,但设置和维护起来很麻烦 - 它们适用于使用良好的查询,但不适用于自定义查询。
  • 为每个事务创建准备好的语句是巨大 数据库命中。如果可以在应用程序级别实现安全性,则更受欢迎。

最后,考虑where子句

emp_tp='abc' and hire_dt=current_dt-'2 years' and super_emp_id is distinct from emp_id

这里有多少个占位符?在将其输入带有占位符的准备好的语句之前,需要对其进行正确解析,对吗?还是我完全错过了船?


主要事实:

  • 为参数化准备好的语句编写 SQL 子句解析器是可行的
  • 编写保证无害的 SQL 子句清理器是不切实际的

解决方法:

对于 SELECTS,随机 SQL 可能是一个问题:既然保护数据库太难了,就让数据库保护自己吧!有不同的用户有不同的 Angular 色/权限。使用只读用户进行选择。对于普通 SQL,这保证了这些语句中没有 DML。

最佳实践:四个 db 用户访问

  1. 开发人员,做所有事情(从不在网络应用程序中用作连接)
  2. dml - 几乎可以对所有内容进行选择/dml(必须用于 dml)
  3. read - 可以选择(用于所有选择,无论是准备好的还是文本)
  4. login - 只能执行登录/密码功能(在登录过程中使用)

密码保护:

  • dmlread 可能无法通过 select 或 dml 访问密码数据
  • login通过 protected 函数访问密码数据,例如,
     function login( username, password ) - returns user_id
     function set_password( usr_id, password ) - sets password
  • 只有 login 可以运行 login()set_password() 函数
  • 根据您的数据库,登录可能需要对密码列进行 sql 访问
  • 根据您的数据库,password 列本身可能受到保护;如果不是,则应该从 user 表中移出到它自己的安全表中

mysql 中使用管理员工具进行设置,大约需要 30 分钟,包括编写登录函数和拆分密码列的时间。

最佳答案

您正在做的是 sql 注入(inject)的定义,无法清除。您不能以安全的方式传入 WHERE 子句故事的结尾。您必须在服务器端构建这部分查询。事实上,您没有意识到这一点意味着您必须阅读更多有关 sql 注入(inject)的信息,明确询问 StackOverflow 是解决此问题的不安全方法。担心的是您可能永远无法了解此漏洞的基础知识。

$order 可以使用白名单以安全的方式完成。例如:

if(in_array($_GET['order'],$list_of_rows)){
   $order=$_GET['order'];
}

如果您传入表名或列名,请确保将其与白名单进行检查,否则这将是 sql 注入(inject)。

关于javascript - sql 注入(inject) - 如何清理程序生成的 sql 子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7291630/

相关文章:

security - 防止机器人进行表单提交

mysql - 如何与 MySQL/PHP 建立安全连接

javascript - 单击按钮后在警报中显示表单值

javascript - 只有一个 y 轴,但位于 Highcharts.js 的右侧

security - 高效的 OAuth2.0 服务器/提供程序如何工作?

mysql - 如何在 MySQL v8 中生成固定数量的行来进行性能测试?

MySQL多索引条件变慢?

javascript - 无法读取未定义的属性 '$apply'

javascript - CHM 文件;有这个格式的标准替代品吗

KDB 中的 SQL 还是我疯了?