受限制的Web应用程序的PostgreSQL权限

use*_*081 10 database postgresql privileges web-applications least-privilege

目标

创建一个有三个用户的数据库并限制他们的权限(我只是大声思考,所以我的用户分离也可以纠正):

  1. 超级用户 - 此用户允许最初的数据库配置.创建应用程序数据库,创建其他用户,设置其权限.默认postgres超级用户适合我,所以这一个完成.
  2. 管理员 - 此用户只能访问在配置期间创建的数据库.管理员可以CRUD所有表中的所有数据,也可以CRUD表等"仅用于此数据库的超级用户"类型的情况.在更新应用程序时,管理员是自动化工具用于处理数据库迁移的用户.
  3. 应用程序用户 - 此用户最终是支持Web应用程序功能的用户.请注意,这与网页上的用户无关 - 这是服务器用来运行查询,插入和删除数据的用户.我明确地希望这个用户能够修改任何东西的权限,也不希望创建/销毁表或索引或任何结构.

我试过的

首先,看看(通常很棒的)PostgreSQL文档,Grant上页面几乎让我眼花缭乱.花了几个小时阅读有关PostgreSQL角色和特权的消息后,我常常感到困惑.我认为通过更多的工作,我将能够确定我想要的管理员用户,但我非常坚持"应用程序用户".我已经知道了这一点(命名和密码都只是占位符):

$ 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
Run Code Online (Sandbox Code Playgroud)

而这就是我不确定的地方.我觉得我要避免的答案是"默认撤销所有内容,然后列举所有不同对象上所有不同级别所需的所有权限".我试图避免这种情况,因为我直接不知道我需要什么.如果这最终成为答案,那么我只需要蹲下来阅读更多,但通常当我开始沿着这样的道路走下去时,我已经错过了一些东西.

问题

如何限制权限,app-user以便他们无法修改任何结构数据(例如,无法添加或销毁表),但能够连接并对行执行任何操作(行级安全性甚至不在我的雷达上).这种特权的一般模型是否与PostgreSQL预期的不同步?如果我必须在"授权"页面上完成每个选项以完成这样的事情,我觉得我错过了一些东西 - 无论是我首先要做的动机还是我正在进行的方式它.

上下文

我正在尝试构建我的第一个端到端Web应用程序.我已经完成了足够的通用软件开发和Web应用程序开发,现在我正在努力了解我通常认为理所当然的日常工作.我正在尝试设置PostgreSQL服务器,同时牢记最小特权原则.

侧面的追求

我还没有在我刚刚加入开发团队的网络应用程序中看到这一点,尽管它们通常都很小并且没有大量使用.这样做真的能做到吗?有没有人有令人信服的理由说明为什么要这样做,或者为什么这是一个坏的或无效的想法?我的假设是,如果我最终得到一个SQL注入漏洞,这将减轻损害,因为数据库用户将具有有限的访问权限.那被误导了吗?

我在这个问题上找到了很好的文章:

Lau*_*lbe 10

我会首先回答你的"副任务"问题:

你完全正确地担心和担忧,设计应用程序的每个人都应该考虑同样的事情.其他一切都是草率和粗心的.

为了减轻成功的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;
Run Code Online (Sandbox Code Playgroud)

但是,如果你采取的至少原则认真,你应该分别授予表的权限和EG不允许app_userDELETEUPDATE数据表中不存在需要用户这样做.

  • 尝试后我从未更新过它,它完全按照我的预期工作。在为网络应用程序设置新数据库时,我大多数时候都会回到这个答案。如果可以的话我会重新投票! (2认同)