我正在处理 SQL intrusion detection system (IDS)我需要解析传入的 SQL 查询。编写自己的 SQL 解析器是一项长期任务,它永远不会准确反射(reflect) native 解析器中使用的逻辑。
我发现 MySQL 有一个主源文件 sql/sql_lex.cc
的词法分析器和一个用来自 sql/sql_yacc.y
的 bison 构建的语法分析器。我真的很想重用这个强大的解决方案。我正在用 C/C++ 构建我的 IDS,所以我正在寻找一些方法将 MySQL 解析器与我的检测系统连接起来。
我想知道是否可以重用 MySQL 解析器(词法+语法分析器)以某种逻辑形式获取 SQL 查询的结构,例如语法树。这有没有可能?有相关的文字、教程或项目吗?
谢谢
最佳答案
作为学士项目的一部分,我已经完成了 IDS 的第一个版本。它作为 MySQL 的插件实现。
我将在下面列出我理解 MySQL 内部结构的主要来源。然后我简要描述了我在 IDS 中使用的方法。
MySQL 文档文本
- 我找到了 Charles Bell 的Expert MySQL 和 Sasha Pachev 的Understanding MySQL Internals(如 user3822447 所写) 是了解 MySQL 内部结构的非常好的切入点。
- MySQL 5.1 插件开发 由 Andrew Hutchings 和 Sergei Golubchik 编写,也非常有用。
- MySQL Internals Manual 还包含一些适合入门的基本信息。
- 阅读所有内容后,我进行了一些调试(使用 VS)并发现了查询树结构的样子。
我的 IDS 解决方案
我的解决方案的源代码可以在 sourceforge 找到强>。我计划在其 wiki 中对其进行更多记录。
主要入口点是 audit_ids.cc
中的 audit_ids_notify()
函数。该插件采用内部 MySQL 解析器生成的查询树,并对其进行了简化(以节省内存)。然后它进行异常检测——它有一个已知查询树结构的列表,并保留关于每个查询树结构的每个参数化部分的一些统计信息。输出被写入MySQL数据目录中的特殊日志文件。
我试图使解决方案模块化和可扩展。初始版本是一种演示,性能没有优化,尤其是在 SQL 存储模块中。
MySQL 插件类型
我确定了 2 种可能的方法并使用了第一种。
- 审计插件
- 我的解决方案插件中的包装类型是 audit plugin .
- 尽管用于报告服务器操作(例如记录查询或错误),我还是使用了这种类型的插件。
- 我选择这种类型的插件是因为我发现这是唯一支持 native 支持的插件,当查询树在完成(即解析)之后和从内存中释放之前调用(对于 MySQL 5.6.17 ).
- 缺点:在未来的 MySQL 版本中不能完全保证以上内容,但我认为这在不久的将来应该不会改变。
- 优点:MySQL不需要重新编译。构建和安装插件就足够了。
- 查询重写插件
- 还有一种替代方法使用非本地插件类型 query-rewrite 强>。它提供了用于修改查询的插件 API,因此也用于读取查询。
- 缺点:要支持此插件 API,MySQL 服务器必须使用该 API 重新编译。我认为可能会成为 MySQL 生产发行版的一部分。
- 优点:专为读取/重写内部查询树而设计的插件类型。
如果有与此主题相关的问题/问题,我可以随时回答;)
关于mysql - 重用 MySQL 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23038620/