addiks/stored-sql

用于在不同环境中处理、建模和执行存储的 SQL(函数、查询、条件等)

v0.1.6 2024-01-11 11:53 UTC

This package is auto-updated.

Last update: 2024-09-11 19:25:52 UTC


README

Build Status Build Status Scrutinizer Code Quality Code Coverage Code Intelligence Status

警告:未完成,正在开发中!

此库提供了一个非常灵活且动态的工具集,用于分析和操作 SQL 语句和 SQL 段落。与其他 SQL 库相比,它可以处理 SQL 片段。像 WHERE foo.bar = "Lorem" 这样的片段是完美的、有效的 SQL 片段。它可能不能在服务器上直接运行(此库知道这一点),但即使查询的其他部分未知或缺失,也可以对其进行处理。

其主要目的是能够将 SQL 部分存储在数据库中,并用作非常灵活、用户自定义的规则,这些规则可以轻松验证并合并到实际运行的 SQL 查询中。

例如,如果您有一个仓储系统,并希望确定哪个仓库应该完成送货,并且希望这个规则可以在任何时候由用户定义和更改,您可以像这样将规则存储在数据库中

如您所见,我们已经在数据库中存储了非常复杂的规则,而不需要任何额外的表,并且可以充分利用完整的 SQL 功能。

安全问题

因此,为了回答显而易见的问题:这不会是一个巨大的安全风险吗?如果有人输入一个像 DROP TABLE orders 这样的“规则”,它不会删除整个 orders 表吗?

答案是:不会,它只会产生错误。

每个 SQL 片段都会被标记化并解析成 AST 树,您只需查看根节点即可理解查询内容。像 LEFT JOIN foo f ON(f.a=b.id) WHERE f.bar=e.baz 这样的片段只会产生两个根节点:一个 SqlAstJoin 节点和一个 SqlAstWhere 节点,因此您可以非常容易地控制允许哪些类型的 SQL 片段,哪些应该被拒绝。

此外,解析器以模块化方式构建,因此您可以限制它所理解的 SQL。您知道在某个时刻,您只期望有简单的 ORDER BY 片段,这些片段由简单的操作和一些函数(如 COUNTSUM)组成,那么只需将这些模块包含在解析器中。如果有人试图偷偷摸摸地提交像 ORDER BY EVAL("DROP TABLE orders") 这样的内容,解析器将拒绝对“EVAL”函数的意外调用。

这也自动排除了任何可能成为漏洞的 SQL 特殊性,因为这些特殊性不包括在这个 SQL 库中(除非您自己编写代码)。

简而言之:此库让您控制允许哪些 SQL,哪些不允许。您定义一个白名单,任何不在白名单上的内容都将被拒绝。(类似于论坛中的 HTML 过滤器)

客户端

此库有两个方面:PHP 的服务器端和 TypeScript 编写的客户端。这两个部分都包含相同的动态 SQL 解析器,但客户端还包含一些 UI 代码,以向用户提供一个易于使用的组件来修改 SQL 部分。毕竟,不是每个人都能理解 SQL。

客户端和服务器端都针对相同的测试用例进行了测试,以确保两个解析器兼容。

警告:客户端尚未完成,需要大量工作。