#postgresql #sql

postguard

测试与CORS类似规则集的Postgres兼容语句

1个不稳定版本

0.1.0 2021年10月20日

#1758数据库接口

MIT 许可证

66KB
1.5K SLoC

Postguard

Latest Version Documentation Crates.io

测试与CORS类似规则集的Postgres兼容语句

为什么

Postgres拥有一个丰富的ROLE系统来管理数据库中的数据权限。但默认情况下,这些权限通常过于宽泛,并且难以通过语句或函数名称来限制。

postguard提供了一种Guard语句分析器,用于保护数据库免受恶意或无效查询的侵害。此Guard可以用于任何在执行前有权访问语句的Rust应用程序(可能是来自不受信任的来源)。在底层,postguard使用libpg_query库将查询解析到语法树,然后在整个树中检查不允许的节点。

安装

postguard添加到您的Cargo.toml

[dependencies]
postguard = "0.1"

用法

use postguard::{AllowedFunctions, AllowedStatements, Command, Guard};

// If AllowedFunctions and AllowedStatements both are set to their 'All' variants
// then no parsing is done and all statements pass the guard
#[test]
fn it_does_nothing_by_default() {
    Guard::new(AllowedStatements::All, AllowedFunctions::All)
        .guard("create table test (id serial primary key)")
        .expect("all statements are permitted by default");
}

// Statements are checked against the list of allowed statements when a 'List' variant
// is provided. Statement-checking is done recursively, so nested disallowed statements
// are also caught by the guard
#[test]
fn it_restricts_statements() {
    let statement_guard = Guard::new(AllowedStatements::List(vec![Command::Select]));

    statement_guard
        .guard("create table test (id serial primary key)")
        .expect_err("privileged statements are restricted");

    statement_guard
        .guard("select * from items")
        .expect("select statements are permitted");

    statement_guard
        .guard("insert into items default values")
        .expect_err("commands in top-level queries are restricted");

    statement_guard
        .guard("
            with cte as (
                insert into items default values
                returning id
            )
            select * from cte
        ")
        .expect_err("disallowed commands in nested queries or expressions are restricted");
}

// Functions are also guarded by name. To disallow all functions, leave the 'List' empty.
#[test]
fn it_restricts_functions() {
    let statement_guard = Guard::new(
        AllowedStatements::List(vec![Command::Select]),
        AllowedFunctions::List(vec!["uuid_generate_v4".to_string()])
    );

    statement_guard
        .guard("select pg_sleep(1)")
        .expect_err("built-in functions and stored procs are restricted");

    statement_guard
        .guard("select uuid_generate_v4() as id")
        .expect("allowed functions are permitted");
}

依赖项

~28MB
~319K SLoC