在限制用户权限的同时动态执行DDL语句的方法

问题描述 投票:0回答:1

因此,我正在尝试使用带有PostgreSQL数据库的.NET Core 2开发Web应用程序,我需要能够记录大量数据。以前我使用动态生成的语句来对数据库执行DDL操作。动态元素以粗体显示的示例:

DO LANGUAGE plpgsql $$ BEGIN IF(SELECT to_regclass('public.item [unique number]'))IS NULL那么CREATE TABLE IF NOT EXISTS item [唯一编号](签名字符变化(50),itemname字符变化(50)。 ..等等

每个表包含大约50个具有特定参数的列。每个项目表包含多个动态行项目类型,并具有各自的列值。

问题是我觉得像这样的动态语句生成是一个巨大的安全漏洞。也许我错了,但感觉就是这样。

我想出了两个选择:

1)创建50个表,表示每个表的前一列,然后在所有50个表中插入INSERT,并在SELECT语句期间为所有表进行JOIN。 (我关心的是这会如何影响性能而不是简单地从1个表中选择所有。我也担心如果其中一个表被破坏/等会影响很多项目,而旧的方式一个损坏的表只影响1个项目。)

2)预先生成大量空表,然后根据需要将记录INSERT到每个空表中,同时跟踪另一个表中的表名。如果需要,存储过程可能会定期生成更多。 (这对我来说就像是一个黑客。)

有没有人建议如何存储这些数据,同时避免客户端发送动态DDL语句?

database postgresql asp.net-core
1个回答
0
投票

你可以保存plpgsql来代替函数并接受参数。你也可以使用format来避免注射,最后你可以检查这个列是否存在,例如:

t=# create or replace function ct(_n text) returns void as $$
begin
select attname into _n from pg_attribute where attname = _n;
if _n is not null then
  execute format('create table if not exists %I()','item'||_n);
end if;
end;
$$ language plpgsql;
CREATE FUNCTION

现在:

t=# select ct(e'\';--hack');
 ct
----

(1 row)

Time: 2.202 ms
t=# \dt item*
No matching relations found.

如果列有效:

t=# select ct('a');
 ct
----

(1 row)

t=# \dt item*
       List of relations
 Schema | Name  | Type  | Owner
--------+-------+-------+-------
 public | itema | table | vao
(1 row)
© www.soinside.com 2019 - 2024. All rights reserved.