基于this问题,我发现我不能指望使用'F'
标识符将函数调用作为代理发现。
我研究得更多,现在我认为postgreSQL使用extended query protocol发送参数语句,如函数。 (如果我错了,请纠正我)
我知道执行prepared-statements也会使用扩展查询协议(我认为应该有更多使用此协议的语句)
所以我认为这不应该是将函数调用识别为代理的方法。还有其他方法吗?有可能吗?还是我完全迷失了,误解了一切?
通过识别函数调用的方式我的意思是我需要识别函数调用并调查传递的参数和函数名称作为前端后端连接中的第三方(客户端和服务器之间)答案 0 :(得分:2)
PostgreSQL对带参数的语句使用扩展查询协议,但这些参数不一定与函数参数相同。
要使用the C API使用示例,如果您发送如下函数调用:
res = PQexec(conn, "SELECT myfun(42)");
它将在包含'Q'
(查询)标识符的数据包中发送。
如果您这样发送:
const Oid types[1] = { INT4OID };
const char * const vals[1] = { "42" };
res = PQexecParams(conn, "SELECT myfun($1)", 1, types, vals, NULL, NULL, 0);
查询将在包含'P'
( Parse )标识符的数据包中发送,参数将在以下'B'
中发送( Bind )数据包。
但这与函数调用无关,对于这样的查询也会发生同样的情况:
SELECT val FROM mytab WHERE id = $1;
你说你的目标是监听前端后端协议并过滤掉所有函数调用和传递给它们的参数。
这是一项非常艰巨的任务;本质上它意味着你必须解析发送到服务器的SQL语句,这意味着你必须复制至少部分PostgreSQL的解析器。您必须记住一些已解析的语句并从绑定包中注入参数。
除此之外,我想到了两个问题:
这样你是否能够捕获函数内部发出的函数调用是否重要?
如何在以下情况下确定传递的参数:
SELECT myfun((SELECT val FROM tab WHERE id = 42));
或者这个:
SELECT myfun(CAST(otherfun(42) || '0' AS integer));
也许有更好的方法来实现你想要的东西,比如攻击PostgreSQL服务器并在实际调用函数的地方提取你的信息。