zoukankan      html  css  js  c++  java
  • 1018.行安全策略

    行安全性策略:对表中的行设置策略,来限制用户和限制操作。

    启用表的行安全性,创建表的行安全策略。

    ALTER TABLE xxxx ENABLE ROW LEVEL SECURITY;

    如果表上不存在策略,将使用一条默认的否定策略,即所有的行都不可见或者不能被修改。

    禁用行安全性不会移除定义在表上的任何策略,它们只是被简单地忽略。

    具有BYPASSRLS属性的超级用户和角色在访问一个表时总是可以绕过行安全性系统。表拥有者通常也能绕过行安全性。

    启用和禁用行安全性以及向表增加策略是只有表拥有者具有的特权。

    每一条策略都有名称并且可以为一个表定义多条策略。

    在某些环境中确保行安全性没有被应用很重要。例如,在做备份时,如果 行安全性悄悄地导致某些行被从备份中忽略掉,这会是灾难性的。

    除可以通过GRANT使用 SQL 标准的特权系统之外,表还可以具有行安全性策略,它针对每一个用户限制哪些行可以被普通的查询返回或者可以被数据修改命令插入、更新或删除。这种特性也被称为行级安全性。

    默认情况下,表不具有任何策略,这样用户根据 SQL 特权系统具有对表的访问特权,对于查询或更新来说其中所有的行都是平等的。

    ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;

    当在一个表上启用行安全性时(使用 ALTER TABLE ... ENABLE ROW LEVEL SECURITY),所有对该表选择行或者修改行的普通访问都必须被一条行安全性策略所允许(不过,表的拥有者通常不服从行安全性策略)。

    如果表上不存在策略,将使用一条默认的否定策略,即所有的行都不可见或者不能被修改。

    应用在整个表上的操作不服从行安全性,例如TRUNCATE REFERENCES

    行安全性策略可以针对特定的命令(增删改查)、角色或者两者。一条策略可以被指定为适用于ALL命令,或者SELECT、 INSERT、UPDATE、或者DELETE。 可以为一条给定策略分配多个角色,并且通常的角色成员关系和继承规则也适用。

    要指定哪些行根据一条策略是可见的或者是可修改的,需要一个返回布尔结果的表达式。对于每一行,在计算任何来自用户查询的条件或函数之前,先会计算这个表达式(这条规则的唯一例外是leakproof函数, 它们被保证不会泄露信息,优化器可能会选择在行安全性检查之前应用这类函数)。使该表达式不返回true的行将不会被处理。可以指定独立的表达式来单独控制哪些行可见以及哪些行被允许修改。

    策略表达式会作为查询的一部分运行并且带有运行该查询的用户的特权,但是安全性定义者函数可以被用来访问对调用用户不可用的数据。

    具有BYPASSRLS属性的超级用户和角色在访问一个表时总是可以绕过行安全性系统。表拥有者通常也能绕过行安全性,不过表拥有者可以选择用ALTER TABLE ... FORCE ROW LEVEL SECURITY来服从行安全性。

    启用和禁用行安全性以及向表增加策略是只有表拥有者具有的特权。

    策略的创建可以使用CREATE POLICY命令,策略的修改 可以使用ALTER POLICY命令,而策略的删除可以使用 DROP POLICY命令。要为一个给定表启用或者禁用行 安全性,可以使用ALTER TABLE命令。

    每一条策略都有名称并且可以为一个表定义多条策略。由于策略是表相关的,一个表的每一条策略都必须有一个唯一的名称。不同的表可以拥有相同名称的策略。

    当多条策略适用于一个给定的查询时,会把它们用OR(对宽容性策略,默认的策略类型)或者AND(对限制性策略)组合在一起。

    这和给定角色拥有它作为成员的所有角色的特权的规则类似。宽容性策略和限制性策略在下文将会进一步讨论。

    作为一个简单的例子,这里是如何在account关系上 创建一条策略以允许只有managers角色的成员能访问行, 并且只能访问它们账户的行:

    CREATE TABLE accounts (manager text, company text, contact_email text);

    ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;

    CREATE POLICY account_managers ON accounts TO managers

        USING (manager = current_user);

    上面的策略隐含地提供了一个与其该约束适用于被一个命令选择的行(这样一个经理不能SELECT、UPDATE或者DELETE属于其他经理的已有行)以及被一个命令修改的行(这样属于其他经理的行不能通过INSERT或者UPDATE创建)。

    如果没有指定角色或者使用了特殊的用户名PUBLIC则该策略适用于系统上所有的用户。要允许所有用户访问users 表中属于他们自己的行,可以使用一条简单的策略:

    CREATE POLICY user_policy ON users

        USING (user_name = current_user);

    这个例子的效果和前一个类似。

    为了对增加到表中的行使用与可见行不同的策略,可以组合多条策略。这一对策略将允许所有用户查看users表中的所有行,但只能修改他们自己的行:

    CREATE POLICY user_sel_policy ON users

        FOR SELECT

        USING (true);

    CREATE POLICY user_mod_policy ON users

        USING (user_name = current_user);

    在一个SELECT命令中,这两条规则被用OR组合在一起,最终的效应就是所有的行都能被选择。在其他命令类型中,只有第二条策略适用,这样其效果就和以前相同。

    也可以用ALTER TABLE命令禁用行安全性。禁用行安全性不会移除定义在表上的任何策略,它们只是被简单地忽略。然后该表中的所有行都是可见的并且可修改,服从于标准的 SQL 特权系统。

    下面是一个较大的例子,它展示了这种特性如何被用于生产环境。表 passwd模拟了一个 Unix 口令文件:

    -− 简单的口令文件例子

    CREATE TABLE passwd (

      user_name             text UNIQUE NOT NULL,

      pwhash                text,

      uid                   int  PRIMARY KEY,

      gid                   int  NOT NULL,

      real_name             text NOT NULL,

      home_phone            text,

      extra_info            text,

      home_dir              text NOT NULL,

      shell                 text NOT NULL

    );

    CREATE ROLE admin;  -− 管理员

    CREATE ROLE bob;    -− 普通用户

    CREATE ROLE alice;  -− 普通用户

    -− 填充表

    INSERT INTO passwd VALUES

      ('admin','xxx',0,0,'Admin','111-222-3333',null,'/root','/bin/dash');

    INSERT INTO passwd VALUES

      ('bob','xxx',1,1,'Bob','123-456-7890',null,'/home/bob','/bin/zsh');

    INSERT INTO passwd VALUES

      ('alice','xxx',2,1,'Alice','098-765-4321',null,'/home/alice','/bin/zsh');

    -− 确保在表上启用行级安全性

    ALTER TABLE passwd ENABLE ROW LEVEL SECURITY;

    -− 创建策略

    -− 管理员能看见所有行并且增加任意行

    CREATE POLICY admin_all ON passwd TO admin USING (true) WITH CHECK (true);

    -− 普通用户可以看见所有行

    CREATE POLICY all_view ON passwd FOR SELECT USING (true);

    -− 普通用户可以更新它们自己的记录,但是限制普通用户可用的 shell

    CREATE POLICY user_mod ON passwd FOR UPDATE

      USING (current_user = user_name)

      WITH CHECK (

        current_user = user_name AND

        shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh')

      );

    -− 允许管理员有所有普通权限

    GRANT SELECT, INSERT, UPDATE, DELETE ON passwd TO admin;

    -− 用户只在公共列上得到选择访问

    GRANT SELECT

      (user_name, uid, gid, real_name, home_phone, extra_info, home_dir, shell)

      ON passwd TO public;

    -− 允许用户更新特定行

    GRANT UPDATE

      (pwhash, real_name, home_phone, extra_info, shell)

      ON passwd TO public;

    在某些环境中确保行安全性没有被应用很重要。例如,在做备份时,如果 行安全性悄悄地导致某些行被从备份中忽略掉,这会是灾难性的。

  • 相关阅读:
    ubuntu上virsh+kvm安装虚拟机
    Less(31)GET-BLIND-IMPIDENCED MISMATCH-Having a WAF in front of web application
    Less(26a)GET
    Less(26)Trick with comments and space (过滤了注释和空格的注入)
    Less(30)Get-Blind Havaing with WAF
    Less(29)基于WAF的一个错误
    Less(25a)Trick with OR & AND Blind (过滤了or和and的盲注)
    Less(25)Trick with OR & AND (过滤了or和and)
    Less(24)Second Degree Injections *Real treat* -Store Injections (二次注入)
    Less(23)GET
  • 原文地址:https://www.cnblogs.com/bufuzhou/p/14214034.html
Copyright © 2011-2022 走看看