VERTICALLY
                            CHALLENGED


                                1

Tuesday, October 20, 2009
Strong Application Permissions,
                         using PostgreSQL

                            Aurynn Shaw, Comman...
APPLICATION
                        ARCHITECTURE
                                  Wherein
            Basic Architecture
...
Basic Architecture

                      Web Server



                      Application       Standard tiered design



...
Basic Architecture

                      Web Server

                                        Standard tiered design
     ...
Layered Communications

                      Web Server


                                        Limitations in
        ...
Layered Communications

                      Web Server
                                        Limitations in
          ...
Application Authority

                      Web Server


                                        The Application becomes
...
Application Authority

                      Web Server

                                        The Application becomes
 ...
Application Authority

                      Web Server
                                         The Application becomes
 ...
Using DB Permissions



            Why ?




                              11

Tuesday, October 20, 2009
Using DB Permissions


            Why ?
                 It’s better than what you have now




                         ...
Using DB Permissions


            Why ?
                 It’s better than what you have now

                 Easy Integr...
Using DB Permissions

            Why ?
                 It’s better than what you have now

                 Easy Integra...
Basic Mechanica
            Entirely DB users
                 Why this is hard to implement




                         ...
Basic Mechanica
            Entirely DB users
                 Why this is hard to implement
            DB users, with an...
Basic Mechanica
            Entirely DB users
                 Why this is hard to implement
            DB users, with an...
DATABASE
                  IMPLEMENTATION
                                Wherein
            Basic Componentry
          ...
Componentry


            Postgres Implementation
                 SET ROLE
                 GRANT / NOINHERIT         Gra...
Componentry

            Postgres Implementation
                 SET ROLE
                 GRANT / NOINHERIT
            ...
Setup
         vc=# CREATE ROLE vc NOINHERIT;
         CREATE ROLE
         vc=# CREATE ROLE auth_level NOLOGIN;
         ...
Setup
         vc=> CREATE TABLE auth_only();
         CREATE
         vc=> REVOKE SELECT ON auth_only FROM
         PUBLI...
sudo for Databases
         vc=> SELECT * FROM auth_only;
         ERROR: permission denied for relation
         auth_onl...
It’s How We Role



            Basic roles




                                   24

Tuesday, October 20, 2009
It’s How We Role


            Basic roles

                 Defines your permissions tree




                            ...
It’s How We Role

            Basic Roles

                 Defines your permissions tree

            Privileged Roles

  ...
It’s How We Role
            Basic Roles

                 Defines your permissions tree

            Privileged Roles

   ...
Your users.can do *this*



                 users.can




                             28

Tuesday, October 20, 2009
A Quick Check
         IF users.can(user_id, ‘type.read’) THEN
           RETURN QUERY
              SELECT * FROM type;
 ...
Wait.. I don’t know you.


                 users.can

                 users.validate




                               ...
User Legitimacy
         CREATE OR REPLACE FUNCTION users.validate
         (
             in_username text,
             ...
The Forge of Users


                 users.can

                 users.validate

                 users.create




      ...
Creating Users
         CREATE OR REPLACE FUNCTION users.create (
             in_username text,
             in_role text...
Basic User Get

                 users.can

                 users.validate

                 users.create

              ...
Collecting Users
         CREATE OR REPLACE FUNCTION users.get (
             in_user_id int
         ) RETURNS users.user...
STANDING ON PYLONS
                                 Wherein
            Exceptions
            Permissions checks
        ...
Exceptions



            Repoze.who cares about 401s and 403s




                                    37

Tuesday, Octobe...
Exceptions


            Repoze.who cares about 401s and 403s

            Trap VC errors in the Application

            ...
Exceptions

            Repoze.who cares about 401s and 403s

            Trap VC errors in the Application

             ...
Once
         class BaseController(WSGIController):
             def __call__(self, environ, start_response):
            ...
I have @needs too!



            Easily Decorate Pylons Views - @needs(‘type.read’)




                                 ...
I have @needs too!


            Easily Decorate Pylons Views - @needs(‘type.read’)

            Using DB permissions in t...
I have @needs too!


            Easily Decorate Pylons Views - @needs(‘type.read’)

            Using DB permissions in t...
I have @needs too!

            Easily Decorate Pylons Views - @needs(‘type.read’)

            Using DB permissions in th...
Pylons in Repose



            The Application Cycle




                                    45

Tuesday, October 20, 2009
Pylons in Repose


            The Application Cycle

            A Basic Repoze Configuration




                        ...
A Basic Configuration
         [plugin:form]
             use =
                 repoze.who.plugins.form:make_redirecting_p...
Pylons in Repose


            The Application Cycle

            A Basic Repoze Configuration

            The Permissions...
The Permissions Swap
         class MetadataProvider(object):
           def add_metadata(self, environ, identity):
      ...
And the Procedure
         CREATE FUNCTION users.become (
             in_user_id int, in_role text
         ) RETURNS VOI...
Pylons in Repose

            The Application Cycle

            A Basic Repoze Configuration

            The Permissions ...
Anonymous Access


            A Wrapping Identifier

            Test For an Identity




                                ...
Wrap the Identifier
         class AnonymousWrapper(object):
           def identify(self, environ):
            i = enviro...
Anonymous Access

            A Wrapping Identifier

            Test For an Identity

            Return a User, or Anonym...
ADVANTAGES,
                   DISADVANTAGES,
                   VULNERABILITIES
                              Wherein
   ...
Advantages


            Same roles in your Procedures, as your Application code

                 Great for consistency

...
Row-Level Example
         PERFORM id FROM table WHERE id = i_id;
         IF FOUND THEN
          PERFORM owner_id FROM t...
Disadvantages



            No PG-backed row-level authorization




                                    58

Tuesday, Oct...
Disadvantages


            No PG-backed row-level authorization

            DDL permissions take work to implement




 ...
Disadvantages


            No direct row-level authorization

            DDL permissions take work to implement

       ...
Disadvantages

            No direct row-level authorization

            DDL permissions take work to implement

        ...
Vulnerabilities


            Any possible PG escalation attack

            SET ROLE could switch to an Admin user

     ...
AND THUS
                             Questions?




                                 63

Tuesday, October 20, 2009
GET IT
      https://projects.commandprompt.com/
            public/verticallychallenged




                             ...
THANK YOU!



                                65

Tuesday, October 20, 2009
Upcoming SlideShare
Loading in …5
×

Vertically Challenged

575 views

Published on

Using database roles to in a WSGI application development stack.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
575
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Vertically Challenged

  1. 1. VERTICALLY CHALLENGED 1 Tuesday, October 20, 2009
  2. 2. Strong Application Permissions, using PostgreSQL Aurynn Shaw, Command Prompt, Inc. PostgreSQL Conference West, 2009 2 Tuesday, October 20, 2009
  3. 3. APPLICATION ARCHITECTURE Wherein Basic Architecture Limitations Points of Authority Why use DB permissions? Implementation 3 Tuesday, October 20, 2009
  4. 4. Basic Architecture Web Server Application Standard tiered design Database 4 Tuesday, October 20, 2009
  5. 5. Basic Architecture Web Server Standard tiered design Application Standard ingress, logic, egress cycle. Database 5 Tuesday, October 20, 2009
  6. 6. Layered Communications Web Server Limitations in Application communication Database 6 Tuesday, October 20, 2009
  7. 7. Layered Communications Web Server Limitations in communication Application Influences on application design Database 7 Tuesday, October 20, 2009
  8. 8. Application Authority Web Server The Application becomes Application permissions arbiter Database 8 Tuesday, October 20, 2009
  9. 9. Application Authority Web Server The Application becomes Application permissions arbiter Loss of Portability Database 9 Tuesday, October 20, 2009
  10. 10. Application Authority Web Server The Application becomes permissions arbiter Application Loss of Portability Increased work for other consumers Database 10 Tuesday, October 20, 2009
  11. 11. Using DB Permissions Why ? 11 Tuesday, October 20, 2009
  12. 12. Using DB Permissions Why ? It’s better than what you have now 12 Tuesday, October 20, 2009
  13. 13. Using DB Permissions Why ? It’s better than what you have now Easy Integration 13 Tuesday, October 20, 2009
  14. 14. Using DB Permissions Why ? It’s better than what you have now Easy Integration Once it’s set up, it’s easier to use 14 Tuesday, October 20, 2009
  15. 15. Basic Mechanica Entirely DB users Why this is hard to implement 15 Tuesday, October 20, 2009
  16. 16. Basic Mechanica Entirely DB users Why this is hard to implement DB users, with an external auth store Still hard Why it’s Worthwhile 16 Tuesday, October 20, 2009
  17. 17. Basic Mechanica Entirely DB users Why this is hard to implement DB users, with an external auth store Still hard Why it’s Worthwhile The Hybrid approach - use The Hybrid approach DB roles + rows in the database, instead of DB users. 17 Tuesday, October 20, 2009
  18. 18. DATABASE IMPLEMENTATION Wherein Basic Componentry Roles Stored Procedures 18 Tuesday, October 20, 2009
  19. 19. Componentry Postgres Implementation SET ROLE GRANT / NOINHERIT Grant / noinherit - How this works together to NOLOGIN provide VC. 19 Tuesday, October 20, 2009
  20. 20. Componentry Postgres Implementation SET ROLE GRANT / NOINHERIT NOLOGIN Great for PCI sudo for the Database compliance 20 Tuesday, October 20, 2009
  21. 21. Setup vc=# CREATE ROLE vc NOINHERIT; CREATE ROLE vc=# CREATE ROLE auth_level NOLOGIN; CREATE ROLE vc=# GRANT auth_level TO vc; GRANT ROLE vc=# 21 Tuesday, October 20, 2009
  22. 22. Setup vc=> CREATE TABLE auth_only(); CREATE vc=> REVOKE SELECT ON auth_only FROM PUBLIC, vc; REVOKE vc=> SET ROLE TO vc; SET vc=> 22 Tuesday, October 20, 2009
  23. 23. sudo for Databases vc=> SELECT * FROM auth_only; ERROR: permission denied for relation auth_only vc=> SET ROLE auth_level; SET vc=> SELECT * FROM auth_only; -- (0 rows) 23 Tuesday, October 20, 2009
  24. 24. It’s How We Role Basic roles 24 Tuesday, October 20, 2009
  25. 25. It’s How We Role Basic roles Defines your permissions tree 25 Tuesday, October 20, 2009
  26. 26. It’s How We Role Basic Roles Defines your permissions tree Privileged Roles The over-arching Container roles User, Moderator, Admin, etc. 26 Tuesday, October 20, 2009
  27. 27. It’s How We Role Basic Roles Defines your permissions tree Privileged Roles The over-arching permissions definitions User, Moderator, Admin, etc. Entry point has LOGIN granted. Entry Point 27 Tuesday, October 20, 2009
  28. 28. Your users.can do *this* users.can 28 Tuesday, October 20, 2009
  29. 29. A Quick Check IF users.can(user_id, ‘type.read’) THEN RETURN QUERY SELECT * FROM type; ELSE exceptable.permission_denied(‘User lacks type.read permissions’);* END IF; * Exceptable function 29 Tuesday, October 20, 2009
  30. 30. Wait.. I don’t know you. users.can users.validate 30 Tuesday, October 20, 2009
  31. 31. User Legitimacy CREATE OR REPLACE FUNCTION users.validate ( in_username text, in_password text ) RETURNS int SELECT users.validate(‘vc’,‘password’); 31 Tuesday, October 20, 2009
  32. 32. The Forge of Users users.can users.validate users.create 32 Tuesday, October 20, 2009
  33. 33. Creating Users CREATE OR REPLACE FUNCTION users.create ( in_username text, in_role text, in_password text ) RETURNS int SELECT users.create(‘user’,‘auth’,md5 (‘password’)); 33 Tuesday, October 20, 2009
  34. 34. Basic User Get users.can users.validate users.create users.get 34 Tuesday, October 20, 2009
  35. 35. Collecting Users CREATE OR REPLACE FUNCTION users.get ( in_user_id int ) RETURNS users.user CREATE TYPE users.user AS ( id int, username text, roles text[] -- Used for app checks ); 35 Tuesday, October 20, 2009
  36. 36. STANDING ON PYLONS Wherein Exceptions Permissions checks Repoze.Who 36 Tuesday, October 20, 2009
  37. 37. Exceptions Repoze.who cares about 401s and 403s 37 Tuesday, October 20, 2009
  38. 38. Exceptions Repoze.who cares about 401s and 403s Trap VC errors in the Application Emit an appropriate 401 or 403 38 Tuesday, October 20, 2009
  39. 39. Exceptions Repoze.who cares about 401s and 403s Trap VC errors in the Application Emit an appropriate 401 or 403 Exceptions are handled ONCE 39 Tuesday, October 20, 2009
  40. 40. Once class BaseController(WSGIController): def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. try: return WSGIController.__call__(self, environ, start_response) except PermissionsError, e: abort(403) except NoSuchUserError, e: abort(401) 40 Tuesday, October 20, 2009
  41. 41. I have @needs too! Easily Decorate Pylons Views - @needs(‘type.read’) 41 Tuesday, October 20, 2009
  42. 42. I have @needs too! Easily Decorate Pylons Views - @needs(‘type.read’) Using DB permissions in the App layer 42 Tuesday, October 20, 2009
  43. 43. I have @needs too! Easily Decorate Pylons Views - @needs(‘type.read’) Using DB permissions in the App layer A single DB query - Not a query per object. 43 Tuesday, October 20, 2009
  44. 44. I have @needs too! Easily Decorate Pylons Views - @needs(‘type.read’) Using DB permissions in the App layer A single DB query - Not a query per object. Why? Multiple tiers are good. 44 Tuesday, October 20, 2009
  45. 45. Pylons in Repose The Application Cycle 45 Tuesday, October 20, 2009
  46. 46. Pylons in Repose The Application Cycle A Basic Repoze Configuration 46 Tuesday, October 20, 2009
  47. 47. A Basic Configuration [plugin:form] use = repoze.who.plugins.form:make_redirecting_plugin login_form_url = /account/login login_handler_path = /account/dologin logout_handler_path = /account/logout rememberer_name = auth_tkt [plugin:auth_tkt] use = repoze.who.plugins.auth_tkt:make_plugin secret = ticket_secret [mdproviders] plugins = vc.repoze:MetadataProvider;browser 47 Tuesday, October 20, 2009
  48. 48. Pylons in Repose The Application Cycle A Basic Repoze Configuration The Permissions Swap 48 Tuesday, October 20, 2009
  49. 49. The Permissions Swap class MetadataProvider(object): def add_metadata(self, environ, identity): if userid: try: from vc.model import user u = user.user(userid) u.become(u.role) except PermissionError, e: if “model” in identity: del identity[“model”] return None identity[“model”] = u 49 Tuesday, October 20, 2009
  50. 50. And the Procedure CREATE FUNCTION users.become ( in_user_id int, in_role text ) RETURNS VOID AS $$ BEGIN IF users.can($1, $2) THEN SET ROLE TO quote_literal($2); ELSE except.permission_denied('User cannot become specified permission level'); END IF; END; $$ LANGUAGE PLPGSQL; 50 Tuesday, October 20, 2009
  51. 51. Pylons in Repose The Application Cycle A Basic Repoze Configuration The Permissions Swap Anonymous Access 51 Tuesday, October 20, 2009
  52. 52. Anonymous Access A Wrapping Identifier Test For an Identity 52 Tuesday, October 20, 2009
  53. 53. Wrap the Identifier class AnonymousWrapper(object): def identify(self, environ): i = environ['repoze.who.plugins'] ['auth_tkt'].identify(environ) if i: # Not anonymous return i else: # Is anonymous # return a really basic anonymousness. return {"repoze.who.userid": anonymous_user_id} 53 Tuesday, October 20, 2009
  54. 54. Anonymous Access A Wrapping Identifier Test For an Identity Return a User, or Anonymous Anonymous users are otherwise identical 54 Tuesday, October 20, 2009
  55. 55. ADVANTAGES, DISADVANTAGES, VULNERABILITIES Wherein Advantages Disadvantages Vulnerabilities 55 Tuesday, October 20, 2009
  56. 56. Advantages Same roles in your Procedures, as your Application code Great for consistency Can Implement Row-level Permissions 56 Tuesday, October 20, 2009
  57. 57. Row-Level Example PERFORM id FROM table WHERE id = i_id; IF FOUND THEN PERFORM owner_id FROM table WHERE owner_id = user_id AND id = i_id; IF NOT FOUND THEN exceptable.permission_denied(‘User does not own specified record.’); END IF; END IF; 57 Tuesday, October 20, 2009
  58. 58. Disadvantages No PG-backed row-level authorization 58 Tuesday, October 20, 2009
  59. 59. Disadvantages No PG-backed row-level authorization DDL permissions take work to implement 59 Tuesday, October 20, 2009
  60. 60. Disadvantages No direct row-level authorization DDL permissions take work to implement No ad-hoc Users 60 Tuesday, October 20, 2009
  61. 61. Disadvantages No direct row-level authorization DDL permissions take work to implement No ad-hoc Users Custom permissions require new entry points 61 Tuesday, October 20, 2009
  62. 62. Vulnerabilities Any possible PG escalation attack SET ROLE could switch to an Admin user User errors a perennial favourite 62 Tuesday, October 20, 2009
  63. 63. AND THUS Questions? 63 Tuesday, October 20, 2009
  64. 64. GET IT https://projects.commandprompt.com/ public/verticallychallenged 64 Tuesday, October 20, 2009
  65. 65. THANK YOU! 65 Tuesday, October 20, 2009

×