欢迎投稿

今日深度:

Oracle最佳替代者PostgreSQL数据库的整体安全性(1)(2)

对这类威胁的反击很简单:不要让普通用户访问或创建任何内容。清单 1 展示了如何对一个表提供保护。


清单 1. 对表提供保护

postgres=# SET SESSION AUTHORIZATION postgres;SETpostgres=# CREATE ROLE user1 WITH LOGIN UNENCRYPTED PASSWORD '123';CREATE ROLEpostgres=# CREATE SCHEMA user1 CREATE TABLE t1(i int);CREATE SCHEMApostgres=# INSERT INTO user1.t1 VALUES(1);INSERT 0 1postgres=# GRANT USAGE ON SCHEMA user1 TO user1;GRANTpostgres=# SELECT I FROM user1.t1; i--- 2(1 row)postgres=# SET SESSION AUTHORIZATION user1;SETpostgres=> SELECT I FROM user1.t1;ERROR:  permission denied for relation t1postgres=> SET SESSION AUTHORIZATION postgres;SETpostgres=# GRANT SELECT ON user1.t1 TO user1;GRANTpostgres=# SET SESSION AUTHORIZATION user1;SETpostgres=> SELECT I FROM user1.t1; i--- 2(1 row)            

清单 2 演示了对 PUBLIC 模式的访问被禁止。


清单 2. 禁止角色 user1 创建任何实体

postgres=> SET SESSION AUTHORIZATION postgres;SETpostgres=# REVOKE ALL PRIVILEGES ON SCHEMA PUBLIC FROM user1;REVOKEpostgres=# SET SESSION AUTHORIZATION user1;SETThe error message of "ERROR:  permission denied for schema user1" means that this    defensive measure works:postgres=> CREATE TABLE X;ERROR:  permission denied for schema user1

访问由其他用户控制的对象

如下面清单 3 所示的攻击媒介假设用户可以访问 PUBLIC 模式;例如,GRANT USAGE ON SCHEMA PUBLIC TO user1。它以下面的假设作为前提:

•所有用户在默认情况下都有权访问集群中的任何数据库。
•假设集群允许用户创建并操作 PUBLIC 模式中的所有实体。
•一个普通用户帐户有权访问系统目录。否则,用户帐户不能正常工作固有的 PostgreSQL 服务器行为)。

清单 3. 收集有关表的信息

postgres=> SELECT * FROM user1.t2;ERROR:  permission denied for relation t2postgres=> insert into user1.t2 values(10);ERROR:  permission denied for relation t2postgres=>postgres=> \d        List of relations Schema | Name | Type  |  Owner--------+------+-------+---------- user1  | t1   | table | postgres user1  | t2   | table | postgres(2 rows)postgres=> \d t?        Table "user1.t1" Column |  Type   | Modifiers--------+---------+----------- i      | integer |        Table "user1.t2" Column |  Type   | Modifiers--------+---------+----------- i      | integer |            

尽管可能无法访问表,但是用户仍然可以收集有关表的信息。

清单 4 展示了用户帐户 user1 获取了一组用户帐户及其各自的属性。普通用户自己无法访问密码。


清单 4. 获取用户帐户的属性

postgres=> select * from pg_user; usename | usesysid | usecreatedb | usesuper | usecatupd | passwd | valuntil | useconfig----------+----------+-------------+----------+-----------+----------+----------postgres | 10 | t | t | t | ******** | | user1 | 18770 | f | f | f | ******** | |(2 rows)

所有用户默认情况下都能够获得集群的定义和模式。

清单 5 展示了一个可以获得有关集群完整定义模式的信息的脚本,方法就是查询系统目录。系统目录可以被超级用户修改或解密,从而减轻了这一威胁。


清单 5. 提取集群范围内的定义

#!/bin/bashpsql mydatabase << _eof_set search_path=public,information_schema,pg_catalog,pg_toast;\t\o list.txtSELECT n.nspname||'.'||c.relname as "Table Name"FROM pg_catalog.pg_class c JOIN pg_catalog.pg_roles r ON r.oid = c.relowner LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespaceWHERE c.relkind IN ('r','')ORDER BY 1;\q_eof_for i in $( cat list.txt ); do psql -c "\d $i"done            

创建和访问由用户定义的函数

函数也分为可信的或不可信的。可信的 过程语言在数据库上下文内执行指令,比如创建表、索引,添加或移除数据,等等。不可信的 过程语言除了可信的特性外)也能够影响真实的世界,比如列出目录的内容,创建或删除文件,调用系统进程,甚至是创建与其他主机的套接字连接。


清单 6. 向数据库添加过程语言并恢复对 user1 的访问

postgres=# create language plpgsql;CREATE LANGUAGEpostgres=# create language plperlu;CREATE LANGUAGEpostgres=# create language plperl;CREATE LANGUAGEpostgres=> SET SESSION AUTHORIZATION postgres;SETpostgres=# GRANT USAGE ON SCHEMA PUBLIC TO user1;GRANT            

清单 7. 可信 vs. 不可信过程语言

postgres=# select lanname as language, lanpltrusted as trusted from pg_language; language | trusted----------+--------- internal | f c        | f sql      | t plperlu  | f plperl   | t(5 rows)            

与表不同的是,普通用户帐户在调用某些用户的函数时不需要特殊权限,即使是由超级用户创建的函数也是如此。


清单 8. 调用超级用户的函数

postgres=# SET SESSION AUTHORIZATION postgres;SETpostgres=# CREATE OR REPLACE FUNCTION public.f1 (postgres(# OUT x textpostgres(# ) ASpostgres-# $body$postgres$# select 'hello from f1'::text;postgres$# $body$postgres-# LANGUAGE SQL;CREATE FUNCTIONpostgres=# SET SESSION AUTHORIZATION user1;SETpostgres=>postgres=> SELECT * FROM f1; x----------------- hello from f1(1 row)

下面清单 9 中的函数由超级用户通过 plperlu 创建。它返回目录的内容;user1 可以调用这个函数。一个普通用户可以同时调用可信函数和不可信函数。要应对这种威胁,最好的方法是通过撤销权限来拒绝对函数的访问。


清单 9. 函数被未授权的用户利用

postgres=> SET SESSION AUTHORIZATION postgres;SETpostgres=# CREATE OR REPLACE FUNCTION public.f2 (postgres(# OUT x textpostgres(# ) ASpostgres-# $body$postgres$# # output the root directory contents into standard outputpostgres$# # notice the use of the single back tickspostgres$# $a = `ls -l / 2>/dev/null`;postgres$# $message = "\nHere is the directory listing\n".$a;postgres$# return $message;postgres$# $body$postgres-# LANGUAGE PLPERLU;CREATE FUNCTIONpostgres=# SET SESSION AUTHORIZATION user1;SETpostgres=> SELECT * FROM f2; x---------------------------------------------------------------------------- Here is the directory listing total 120 drwxr-xr-x 2 root root 4096 Aug 29 07:03 bin drwxr-xr-x 3 root root 4096 Oct 11 05:17 boot drwxr-xr-x 3 root root 4096 Nov 26 2006 build lrwxrwxrwx 1 root root 11 Aug 22 2006 cdrom -> media/cdrom drwxr-xr-x 15 root root 14960 Oct 12 07:35 dev drwxr-xr-x 118 root root 8192 Oct 12 07:36 etc(1 row)            

清单 10. 针对 user1 和组 PUBLIC 提供保护

postgres=# SET SESSION AUTHORIZATION postgres;SETpostgres=# REVOKE ALL ON FUNCTION f2 FROM user1, GROUP PUBLIC;REVOKEpostgres=# SET SESSION AUTHORIZATION user1;SETpostgres=> SELECT * FROM f2;ERROR: permission denied for function f2postgres=>

清单 11 展示了信息收集。


清单 11. 获取函数的源代码

postgres=> SET SESSION AUTHORIZATION user1;SETpostgres=> select prosrc as "function f3" from pg_proc where proname='f3'; function f3---------------# output the root directory contents into standard output# notice the use of the single back ticks $a = `ls -l / 2>/dev/null`; $message = "\nHere is the directory listing\n".$a; return $message;(1 row)


www.htsjk.Com true http://www.htsjk.com/shujukuaq/16816.html NewsArticle 对这类威胁的反击很简单:不要让普通用户访问或创建任何内容。清单 1 展示了如何对一个表提供保护。 清单 1. 对表提供保护 postgres=# SET SESSION AUTHORIZA...
评论暂时关闭