首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SET会话授权多用户mod-perl2 2连接缓存的安全设计

SET会话授权多用户mod-perl2 2连接缓存的安全设计
EN

Stack Overflow用户
提问于 2013-12-12 15:28:14
回答 2查看 537关注 0票数 0

我有一个mod_perl2.0.4 /Apache2.2Web应用程序运行在CentOS 6.4和PostgreSQL 9.0上。

直到最近,对于所有连接,我都使用了this setup:Apache::DBI和DBI->connect_cached,即使在我是唯一用户的开发区域,它也开始为FATAL: sorry, too many clients already提供服务。

为了调试这一点,我删除了对Apache::DBI的所有引用,升级到最新的DBI,并将所有出现的connect_cached替换为纯DBI->connect。在我看来,现在建立的连接稍微少了一些,然后离开了<IDLE>。但是,我意识到我并没有在所有语句句柄上调用disconnect(),因为在Apache::DBI下听起来没有什么不同。

我的连接当前将所有连接都作为同一个用户连接,然后通过设置会话授权降低他们基于哪个用户的权限。我这样做是因为使用数据库的其他应用程序允许一个密码登录,它可以将凭据直接传递给数据库,但是这个特定的web应用程序使用了一个荣誉系统登录屏幕,您只需单击您的名字即可登录。所以现在是未来-安全准备,但方便-启用。此外,历史记录和类似的数据库触发器依赖于正确设置的会话用户来跟踪谁做了什么。

因为我担心一个数据库句柄被错误的会话用户重用,所以我将{ private_user_login => $login_role_name, PrintError => 0, RaiseError => 1, AutoCommit => 1}传递给connect_cached,以便按用户区分每个连接。但是,由于我总是在连接后立即设置会话授权,所以我认为private_user_login散列所做的全部工作就是使给定的Apache进程至少有与用户相同的创建和空闲的DB连接,如果最终每个用户都能够随机使用给定的Apache进程的话。同时,因为我没有断开任何手柄,它们最终会被耗尽。

我的问题是,是否可以安全地取出private_user_login使所有连接句柄看起来相同,以减少未打开的连接数量,还是一个连接句柄可以在脚本中间(在设置会话用户之后)被另一个用户重新使用,从而创建一个争用条件?另外,尽管Apache::DBI的文档说我不需要删除disconnect()调用,但我是否应该在每个脚本的末尾都有这样的调用,以便Apache::DBI可以决定是否断开连接?

换句话说,如果没有我的私有连接变量,那么在下一个Apache::DBI->connect()重用现有连接时,SET会话授权的效果会持续吗?如果是这样的话,是否有可能在一个请求当前正在执行但目前没有使用数据库句柄时,另一个请求重新使用一个连接?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-17 00:37:27

看上去很安全。要“验证”,您可以创建这样的人工竞赛条件:

代码语言:javascript
复制
use Apache2::RequestUtil;
use Apache2::RequestRec;
my $r = Apache2::RequestUtil->request;
$r->headers_out->add('Cache-control' => "must-revalidate, no-cache, no-store");
require Apache2::Request;
my $req = Apache2::Request->new($r);
$r->content_type("text/html");
my $login_role_name = $req->param('u');
$r->print($u);
$r->print('<br>' . $$);
use DBI;

my $dbh = DBI->connect_cached("dbi:Pg:dbname=......,{ RaiseError => 1, AutoCommit => 1});
$dbh->do("set session authorization ?; ", undef, $login_role_name);
{
    use warnings NONFATAL => 'all';
    my $rows = $dbh->selectall_arrayref('select pg_backend_pid(), current_user::text');
    warn "pg ${$$rows[0]}[0] mp $$ auth: ${$$rows[0]}[1] original auth: $login_role_name";
    sleep 10;
    $rows = $dbh->selectall_arrayref('select pg_backend_pid(), current_user::text');
    warn "pg ${$$rows[0]}[0] mp $$ auth: ${$$rows[0]}[1] original auth: $login_role_name";
}

然后...and用两种不同的“?u=.”击中它。URL。auth将始终与原始auth匹配,因为dbh在仍在执行的脚本中时不可分发。

票数 0
EN

Stack Overflow用户

发布于 2013-12-13 03:42:11

如果可以的话,我推荐一种稍微不同的策略。

在Apache中保持简单。使用每个用户的私有会话,如果这是最容易使安全和可靠的。

然后在PgBouncer服务器和Apache实例之间放置一个PostgreSQL。将其设置为事务池模式。当连接在用户之间切换时,它将很高兴地复用您的连接,并负责调用丢弃的所有连接。

我认为您仍然可以对通过PgBouncer建立的连接使用SET会话授权。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20547480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档