我有一个项目(私有,ASP.net网站,密码用https保护),其中一个要求是用户能够输入将直接查询数据库的Sql查询.我需要能够允许这些查询,同时防止它们对数据库本身造成损害,以及访问或更新它们无法访问/更新的数据.
我已经提出了以下实施规则:
使用仅具有Select Table/View和Update Table权限的db用户(因此任何其他命令,如drop/alter/truncate/insert/delete都不会运行).
验证语句以"选择"或"更新"字样开头
验证(使用正则表达式)语句中没有没有单引号,空格和字母包围的分号实例.(这里的想法是,他们可以包含第二个查询的唯一方法是使用不是输入字符串一部分的分号结束第一个查询.
验证(使用Regex)用户是否有权访问正在查询/更新的表,包括在连接中等.这包括任何子查询.(实现这一目标的部分方式是用户将使用一组实际上不存在于数据库中的表名,部分查询解析将用正确的相应表名替换为查询) .
我错过了什么吗?
目标是用户能够以他们认为合适的任何方式查询/更新他们有权访问的表,并防止任何意外或恶意企图破坏数据库.(并且由于要求是用户生成sql,我无法使用我所知道的任何内置工具对查询进行参数化或清理它).
这是一个坏主意,而不仅仅是从注射预防的角度来看.对于不知道更好的用户来说,如果不小心运行会占用所有数据库资源(内存/ CPU)的查询,实际上很容易,从而导致拒绝服务攻击.
如果必须允许这样做,最好为这些查询保留一个完全独立的服务器,并使用复制使其非常接近生产系统的精确镜像.当然,这不适用于您的UPDATE要求.
但我想再说一遍:这不行.如果用户可以运行即席查询,则无法保护数据库.