创建一个包含三个用户的数据库并限制他们的权限(我只是大声思考,所以我的用户分离也可以纠正):
postgres
超级用户适合我,所以这一个已经完成。首先,看一下(通常很棒的)PostgreSQL文档,page on Grant几乎让我眼花缭乱。花了几个小时阅读有关PostgreSQL角色和特权的消息后,我常常感到困惑。我认为通过更多的工作,我能够确定我对管理员用户的要求,但我很难坚持使用#34; app用户"。我已经掌握了这一点(命名和密码都只是占位符):
$ psql -U postgres
postgres=# CREATE USER "app-admin" WITH PASSWORD 'password';
CREATE ROLE
postgres=# CREATE USER "app-user" WITH PASSWORD 'password';
CREATE ROLE
postgres=# CREATE DATABASE "test-database" WITH OWNER "app-admin";
CREATE DATABASE
postgres=# \c "test-database"
You are now connected to database "test-database" as user "postgres".
test-database=# DROP SCHEMA "public";
DROP SCHEMA
test-database=# CREATE SCHEMA "app" AUTHORIZATION "app-admin";
CREATE SCHEMA
这是我不确定的地方。我觉得我试图避免的答案是"默认情况下撤销所有内容,然后列举你在所有不同对象的所有不同级别上需要的所有权限"。我试图避免这种情况,因为我直接不知道我在那里需要什么。如果这最终成为答案,那么我只需要蹲下来阅读更多,但通常当我开始沿着这样的道路走下去时,我已经错过了一些东西。
如何限制app-user
的权限,以便他们无法修改任何结构数据(例如,无法添加或销毁表),但能够连接并对行执行任何操作(行级安全性甚至不在我的行上)雷达)。这种特权的一般模型是否与PostgreSQL预期的不同步?我觉得如果我不得不通过其中的每一个选项,我都会错过一些东西" grant"完成这样的事情的页面 - 无论是我最初做这件事的动机,还是我做这件事的方式。
我正在尝试构建我的第一个端到端Web应用程序。我已经做了足够的通用软件开发和Web应用程序开发,现在我正在努力理解我通常每天都认为理所当然的部分。我正在尝试设置PostgreSQL服务器,同时牢记principle of least privilege。
我还没有在网络应用程序上看到这种情况,我只是加入了开发团队,尽管他们通常很小并且没有大量使用。这样做真的能做到吗?有没有人有令人信服的理由说明为什么要做这样的事情,或者为什么这是一个坏的或无效的想法?我的假设是,如果我最终得到一个SQL注入漏洞,这将减轻损害,因为数据库用户将具有有限的访问权限。这是误入歧途吗?
答案 0 :(得分:8)
我首先回答你的“求职”问题:
对于您的担忧和担忧,您完全正确,并且设计应用程序的每个人都应该考虑相同的事情。其他一切都是草率和粗心。
为了减轻成功的SQL注入攻击可能造成的损害,您绝对应该采用最小权限原则。
设置符合您要求的系统应该非常简单。
我会使用你的exaple中的对象名称,除了我会使用下划线而不是minus。在对象名称中仅使用小写字母,下划线和数字是很好的,因为它会让您的生活更轻松。
/* create the database */
\c postgres postgres
CREATE DATABASE test_database WITH OWNER app_admin;
\c test_database postgres
/* drop public schema; other, less invasive option is to
REVOKE ALL ON SCHEMA public FROM PUBLIC */
DROP SCHEMA public;
/* create an application schema */
CREATE SCHEMA app AUTHORIZATION app_admin;
/* further operations won't need superuser access */
\c test_database app_admin
/* allow app_user to access, but not create objects in the schema */
GRANT USAGE ON SCHEMA app TO app_user;
/* PUBLIC should not be allowed to execute functions created by app_admin */
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin
REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
/* assuming that app_user should be allowed to do anything
with data in all tables in that schema, allow access for all
objects that app_admin will create there */
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT SELECT, USAGE ON SEQUENCES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT EXECUTE ON FUNCTIONS TO app_user;
但如果你采取最不严肃的原则,你应该单独授予表格权限,例如表格中不允许app_user
到DELETE
和UPDATE
数据,用户无需这样做。
答案 1 :(得分:1)
对于Web应用程序,我将权限分为三个角色,每个角色都继承自其前任角色。
这样,即使某些黑客设法进行SQL注入,他也只能使用所使用角色的权限,通常只有SELECT或INSERT。
我的网络应用程序通常不需要像CREATE,DROP,TRUNCATE等更具侵入性的权限,因此我不会将这些权限授予网络应用程序。
在第二个角色需要更新或删除某些内容的极少数情况下,我要么为该特定表授予权限,要么将代码放在使用SECURITY DEFINER
创建的函数中。
/** role_read is read-only with SELECT and EXECUTE */
CREATE ROLE role_read;
/** role_read_add adds INSERT */
CREATE ROLE role_read_add;
/** role_read_add_modify adds UPDATE and DELETE */
CREATE ROLE role_read_add_modify;
GRANT USAGE ON SCHEMA <schema> TO role_read;
/** for existing objects */
GRANT SELECT ON ALL TABLES IN SCHEMA <schema> TO role_read;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA <schema> TO role_read;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA <schema> TO role_read;
/** for future objects */
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT SELECT ON TABLES TO role_read;
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT SELECT ON SEQUENCES TO role_read;
/** role_read_add inherits from role_read */
GRANT role_read TO role_read_add;
/** for existing objects */
GRANT INSERT ON ALL TABLES IN SCHEMA <schema> TO role_read_add;
GRANT ALL ON ALL SEQUENCES IN SCHEMA <schema> TO role_read;
/** for future objects */
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT INSERT ON TABLES TO role_read_add;
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT ALL ON SEQUENCES TO role_read_add;
/** role_read_add_modify inherits from role_read_add */
GRANT role_read_add TO role_read_add_modify;
/** for existing objects */
GRANT UPDATE, DELETE ON ALL TABLES IN SCHEMA <schema>
TO role_read_add_modify;
/** for future objects */
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT UPDATE, DELETE ON TABLES TO role_read_add_modify;