Re: SE-PgSQL patch review

From: KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com>
To: Itagaki Takahiro <itagaki(dot)takahiro(at)oss(dot)ntt(dot)co(dot)jp>
Cc: KaiGai Kohei <kaigai(at)kaigai(dot)gr(dot)jp>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: SE-PgSQL patch review
Date: 2009-11-26 04:25:22
Message-ID: 4B0E0332.6060307@ak.jp.nec.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Itagaki Takahiro wrote:
> KaiGai Kohei <kaigai(at)kaigai(dot)gr(dot)jp> wrote:
>> -- keep it smaller, and step-by-step enhancement
>
> I'd prefer "smaller concept" rather than "smaller patch".

Its difference is unclear for me.

In this CF, I separated most of separatable concepts to reduce
size of the patch, as follows:
- No access controls except for databases, schemas, tables and columns
- No row-level access control granurality
- No security OID and text translation
- No access control decision cache

Needless to say, these feature can be added later, step-by-step.
But the core of SE-PgSQL is access control based on the SELinux policy.
It is an atomic feature, so unseparatable.

> ==== No interaction with existing features ====
> * SE-PgSQL injects security-context-based access control, but there are
> no interaction between it and the existing role-based access control.

If the interaction means restriction of available pairs between
a certain database role and a certain security context of the
client, it may be available as I followed on the next section.

However, SELinux accept only security context as an identifiers
of processes, files, tables and so on. If you mention to consider
database role identifier in access control decision, it is not
possible.

> * SE-PgSQL introduces concept of "security context", but there are
> no interaction between it and the existing context-related features.
> (ex. pg_hba.conf and Application name patch)
>
> This is just an idea, but how about implementing context-based access
> control based on role-based ACL? We will not use security context directly
> for access control, but it forbid to use ROLEs in some conditions.
> An example of implementation image is:
>
> =# ALTER ROLE role VALID ON SECURITY CONTEXT '...'
>
> For example, this could allow us to modify rows only with a particular
> application, only from particular machine, and only in particular hour.
> Since we've already supported object- and column-level ACL, I think
> we can the same capability of the patch using security-context-to-role
> mapper. Or, is it not ideal in the policy of SELinux?

Basically, it is not bad idea to restrict available database roles by
the security context of the client.
However, we need to revise the concept a bit.

Please remind its principle. SE-PgSQL applies all the its access controls
according to the security policy of SELinux.
SELinux defines all the access control rules as a relationship between
a couple of security contexts.

So, this idea can be rewritten as follows:

1. add a security context to pg_authid system column
2. add db_role object class in the security policy
(It needs discussion in the SELinux community)
3. It checks db_role:{loginas} permission between the client and
the security context of the db_authid entry.

For example, if the security policy allows "system_u:system_r:httpd_t:s0"
(a typical web server) domain to login as a database role labeled as
"system_u:object_r:web_role_t:s0", we can assign this context on a certain
database role to be performs as web users.

ALTER ROLE role SECURITY CONTEXT ( 'system_u:object_r:web_role_t:s0' );

Please note that I basically agree to implement this relationshipt,
but it can be implemented as an incremental patch, as long as the
core feature is merged first.

> ==== Postgres is not prepared to receive SE-PgSQL ====
> We depend on superuser too heavily. As KaiGai-san mentioned, we use
> "if (superuser())" instead of ACL in some places. It is a bad manner.
> We should centralize access control in one module (maybe aclcheck.c),
> and SE-PgSQL should be implemented only in the module.
>
> If possible, it might be good for SE-PgSQL to replace all of the
> role-based access control layer in postgres because it is hard for
> users to maintain both Postgres ROLEs and SELinux settings consistently.
> Do we need pluggable ACL layer before accepting SE-PgSQL?

I already tried this approach in the commit fest#2.
But it was a big failure. :(

I don't think it is a right direction.

In addition, former cases (SELinux, X-window, ...) does not integrate
its default access control stuff and the optional access controls.

> ==== Need to reconsider row-level security control ====
> Row-level security control is excluded from the patch, but we'd better
> also considering it at first. You mentioned as:
>
>> In SELinux model, massive number of objects shares a limited number of
>> security context (e.g more than 100 tables may have a same one)
>
> but I'm not sure what application do you suppose. For example,
> if we protect web application from SQL injection attacks, the
> password column for each row can be read only from the end user
> represented by the row. The number of security labels will be same
> as the number of end users (= rows).

I need to admit the current proposal is a "lite" version, so some of
functionality may be lack.

For example, see the page.24 of this slids:
http://sepgsql.googlecode.com/files/JLS2009-KaiGai-LAPP_SELinux.pdf

It assigns a certain security context on web-applications for each
virtual host. In this example, a web-application once labeled as "blue"
can never access both of filesystem objects and database objects (such
as tables) labeled as other colors. SELinux performs as a logical wall
to separate individual domains.
Nowadays, we can often see such a multi-tenant system.

I'd like you to understand that I separated most of separatable features
as a result of the previous discussions, such as row-level granurality,
access control decision cache, translater between security OID and text
and so on.

> ==== Actual benefits of SE-PgSQL ====
> SE-PgSQL will be committed step-by-step -- but could you explain which step
> can solve which problem in the real world? Imagine that SQL injections,
> measure for SOX Act, divulgation of personal information, .... They are
> security holes in terms of a whole application, but not a hole in terms of
> database, because database cannot always distinguish between legal and
> illegal data access (ex. correction of wrong data vs. rigging of benefits).

Good question. The hardness to fix all the security holes in application
is the original motivation of reference monitor model (it is a conceptual
design in 80's security reserch. SELinux and other MAC system is on the
genealogy).

Please imagine the reason why SELinux applies its access control policy
on the accesses to system resources via system-calls.

If we have to fix all the application bugs, it looks like a endless-war.
The number of strategic points to be checked are infinite in fact.
However, all the application has to use system-calls to access system
resources such as files, networks, etc. It means we can aquire any
accesses without exceptions with hooks in operating system, even if
violated accesses are not bugs in operating system.

The operating system also cannot distinguish whether the given access
is actually a licit one, or not. But it prevent violated access in the
outline.
For example, when a user tries to write a file, SELinux cannot know
whether the contents is right or not. But if a "unclassified" user
tries to write something on a "classified" file, SELinux will prevent
this request independent from the correctness of the contents.

Please note that SELinux/SE-PgSQL never deny existing access control
model. They have their own purpose and whorth, we never deny it.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com>

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2009-11-26 04:34:35 Re: garbage in psql -l
Previous Message Tom Lane 2009-11-26 04:16:51 Re: Deleted WAL files held open by backends in Linux