使用正则表达式验证SQL查询

3
我希望您能够验证包含以下单词的字符串:SELECTFROM,但不包含像CREATEDROPUPDATE等一组单词。
更具体地说,我想确保用户只能在我的系统上执行SELECT查询语句。
到目前为止,我得到的正则表达式如下:
^(?!.*(CREATE|DROP|UPDATE|INSERT|ALTER|DELETE|ATTACH|DETACH)).*$

但是,我怎么知道字符串中是否按正确顺序包含了SELECTFROM,如下所示: SELECT .... FROM ....

正则表达式的更多要求。如果查询类似于以下情况,则希望正则表达式有效: 1. SELECT * FROM TABLE WHERE NAME ='ALTER' 2. SELECT * FROM TABLE WHERE FILENAME ='ATTACHMENT' 3. 如果组中有任何单词:ALTER, DROP等,并且每个单词之前和之后都有一个空格,则正则表达式需要无效。

关于第一个问题:如果某人的名称为“ALTER JOHN”,那么查询将无效,这是不正确的。

感谢您告诉我这是一个坏主意。我同意并知道。没有风险,每个用户都将拥有自己的数据库。问题是关于正则表达式的。谢谢! 此外,查询将在SQLITE数据库上运行


提前感谢!


4
老实说,解决只允许用户执行SELECT语句的问题更好的方法是在SQL服务器中创建一个仅具有SELECT权限的用户。该链接详细介绍了如何授予和撤销SQL Server中的对象级权限。 - Scott Chamberlain
可能是正则表达式匹配常见SQL语法?的重复问题。 - Liam
1
不要这样做。这是一个坏主意。 - Liam
1
每个用户将拥有自己的数据库...哦天啊。你也应该问另一个关于这个问题的问题 :-) - Tim Biegeleisen
关于您的更新,当一位专业承包商问您:“客户要求我建造和安装一个定制的货架系统。我现在需要钉它,但我不确定用什么来敲钉子。我应该使用旧鞋还是玻璃瓶?”时,您应该回答“都不是,您的方法是错误的,您应该使用锤子来完成这种工作。 - Scott Chamberlain
显示剩余4条评论
2个回答

4
您可以添加一个正向前瞻,用于检查是否存在"SELECT ... FROM":
^(?=.*SELECT.*FROM)(?!.*(?:CREATE|DROP|UPDATE|INSERT|ALTER|DELETE|ATTACH|DETACH)).*$

虽然这回答了你的问题,但我有些担心,因为你标记了C#,这意味着你需要从C#应用程序中执行此操作。通常情况下,您应该不要让外部输入的原始SQL代码在C#代码中执行。相反,在运行查询之前,请始终使用准备好的语句,以便可以安全地消毒用户输入。
如果您想进行不区分大小写的匹配,请在创建正则表达式时使用RegexOptions.IgnoreCase标志:
Regex rgx = new Regex(@"^your pattern$", RegexOptions.IgnoreCase);

我知道你的意思,但这才是我真正想要的。非常感谢!关于你的回答,那个正则表达式是区分大小写的,我该如何去掉它? - Michael Commons
谢谢!在我能接受答案之前,我需要等待10分钟。 - Michael Commons
4
声明 @sql 为 varchar(max) 类型;将字符串 'DRO' 赋值给 @sql 变量;将字符串 "P TABLE SomeImportantTable" 连接到 @sql 变量后面;使用 sp_executesql 执行动态 SQL 语句。 - Scott Chamberlain
@ScottChamberlain 我提出了一个警告,如果是从C#应用程序中进行操作,应该使用语句。在这种情况下,用户甚至无法选择要执行的语句,除了无法将任何内容注入查询之外。 - Tim Biegeleisen
1
@TimBiegeleisen,这条评论更多是为了强调您对OP的警告,而不是与您的答案不同意。 - Scott Chamberlain

0
const regex = /(\s*([\0\b\'\"\n\r\t\%\_\\]*\s*(((select\s+\S.*\s+from\s+\S+)|(insert\s+into\s+\S+)|(update\s+\S+\s+set\s+\S+)|(delete\s+from\s+\S+)|(((drop)|(create)|(alter)|(backup))\s+((table)|(index)|(function)|(PROCEDURE)|(ROUTINE)|(SCHEMA)|(TRIGGER)|(USER)|(VIEW))\s+\S+)|(truncate\s+table\s+\S+)|(exec\s+)|(\/\*)|(--)))(\s*[\;]\s*)*)+)/i;

这个正则表达式检查输入是否包含SQL查询。 https://regex101.com/r/XxO2J3/5


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接