Professional Documents
Culture Documents
------------------------------------------------
PART II
Author JP Vijaykumar Oracle DBA
A detailed discussion on the setup and implementation of Virtual Private Database / Transparent Data
Encryption is beyond the scope of this document.
Please refer to Oracle’s Metalink for a detailed discussion on Virtual Private Database setup and
Transparent Data Encryption setup
Though the title says “A SIMPLE SECURITY APPROACH PART II”, the topics covered in this article are
COMPLEX in nature. Welcome to the world of complexities in database access and security.
This document describes setting up column level / row level security of data through custom built views,
and a critical review on the creation and maintenance of procedures for truncating tables in third party
schemas.
0201 Protecting sensitive / confidential data using column level / row level security through
custom built views.
Managing specific and special requirements of application developers is always a challenge. The
present day DBA needs to know the practicability of these requirements in the Oracle
environment. Weighs the merits and demerits of implementation of such special requirements
and their impact on the application.
0201 Protecting sensitive / confidential data using column level / row level security
through custom built views
For my designing and modeling of views, I work with scott.emp table. Assuming that all users
logging into the database are having their employee details available in scott.emp table. All users
are given select permissions on the view. Any user whose employee details are not available in
the scott.emp table will get 0 rows as output from the custom built view.
Connect as scott
select * from scott.emp;
14 rows selected.
Create a user for accessing the data from our custom built view.
Create user blake identified by blake account unlock;
Grant create session to blake;
Version II – Details of the login user and users who work for this user are also displayed
create or replace view emp_jp_view as
select a.empno, a.ename, a.job, a.mgr, a.hiredate,a.sal,a.comm,a.deptno
from scott.emp a,
(select ename from scott.emp
Connect by prior empno = mgr
Start with ename in (select sys_context('USERENV','SESSION_USER') username from dual)) b
where a.ename = b.ename;
connect as blake
select * from gzbgqt.emp_jp_view;
6 rows selected.
Imposing COLUMN Level security:
Version III – Only the login user’s details are displayed
As per the logic implemented in the view creation, only the user KING is authorized to see the sensitive
and confidential columns in the scott.emp table. Any user logging as KING can see all the columns in the
tables. All others can see the columns EMPNO, HIREDATE and DEPTNO, the rest of the columns in the
view are masked.
We can also include a list of employees into our logic, who can see all the columns from the view.
Connect as blake
Select * from gzbgqt.emp_jp_view;
14 rows selected.
As the connected user is not KING, all the columns of the view are not displayed.
Imposing ROW Level and COLUMN level security:
Version IV – Only the login users details are displayed.
View created.
Connect as blake
select * from gzbgqt.emp_jp_view
Version V – Details of the login user and others who work for this user are also displayed
Create or replace view
emp_jp_view
as
select
a.empno,
case when a.ename in (select ename from scott.emp connect by prior empno = mgr Start with ename in
(select sys_context('USERENV','SESSION_USER') username from dual))
then a.ename else '***' end ename,
case when a.ename in (select ename from scott.emp Connect by prior empno = mgr Start with ename in
(select sys_context('USERENV','SESSION_USER') username from dual))
then a.job else '***' end job,
case when a.ename in (select ename from scott.emp connect by prior empno = mgr Start with ename in
(select sys_context('USERENV','SESSION_USER') username from dual))
then a.mgr else null end mgr,
a.hiredate,
case when a.ename in (select ename from scott.emp connect by prior empno = mgr Start with ename in
(select sys_context('USERENV','SESSION_USER') username from dual))
then a.sal else 0 end sal,
a.comm,
a.deptno
from scott.emp a;
connect as blake
select * from gzbgqt.emp_jp_view
14 rows selected.
Any user with DBA role or DROP ANY TABLE system level privilege can TRUNCATE tables in others’
schemas. Any schema owner can truncate tables in his/ her schema.
In secure production environments, it is not a good practice to grant DBA role / DROP ANY TABLE
system level privilege to users, for this purpose.
The workaround is to create a procedure in a scheme, who is granted DBA role or DROP ANY TABLE
system level privilege. In turn grant execute permissions on the truncate table procedure to the users, who
need truncate privileges on other schemas’ tables.
The above truncate table procedure is a simple procedure. Whoever is granted EXECUTE privileges on the
procedure can truncate any table in the database. It is a time bomb.
In the event, this procedure is misused in a production / or secure environment, imagine the trouble to
recover the lost data
It is not a good practice to use generic truncate table procedures in production / or secure environments. For
a more secure truncate table procedure, please refer my article
“URL FOR SECURE TRUNCATE TABLE PROCEDURE MY PREVIOUR ARTICLE”
Day in and day out, sensitive and confidential data is stolen from everywhere. In protecting the sensitive
and confidential data from the unauthorized and hackers, using data modeling and custom built views, the
options are endless and unimaginable.
If my prime objective is to protect confidential data from hackers and unauthorized access. My simple
approach is DEVIDE AND CONQUER. I will keep my trillion dollars in a safe that can only be opened
with 10 KEYS. NOT WITH A SINGLE KEY. Even if I loose 9 KEYS out of 10, there is no harm. My
money is safe. But if the safe can be opened with a SINGLE key and that single key is lost. Then all is lost.
Depending on the sensitivity of data and business requirements, the hierarchical structure of
employee details may be stored in one denormalized table or in more normalized tables. It is a
good practice to store the employee details in more normalized tables than in one denormalized
table. To further protect the data from unauthorized access and hackers, create the tables in
different schemas. Even you can move these different schema tables into different databases.
No matter how hard you protect the data in its entirety, it is theft prone. So dismember your data and
protect it. Redefine the database access to each schema. And only few users can access all these schema
tables to create the full picture. Grant SELECT permission on the custom built view to the end users. And
users accessing the view can only see their own data. No other’s data is visible. Create public synonym for
the view.
When you partition the table horizontally, the records in their entirety are segregated into separate
partitions, depending on the partition key ranges.
Partition the table vertically into smaller tables with few columns each. Unless all the partitions are joined
together, the complete record can not be constructed. Data from a single vertical partition is not complete.
So I will cut my scott.emp table, which holds sensitive and confidential data, into vertical partitions.
Like
Desc scott.name [scott.n101] {scott.n101@test} (scott.n101@dallas)
Empno varchar2(10)
Firstname varchar2(20)
Lastname varchar2(20)
It is a good strategy to keep the view and its parent tables in different schemas / or databases. The viability
of application to populate the vertically partitioned scott.emp table across schemas / databases is to be take
care of before moving the vertical partitions across schemas / databases.
For this secure data model to work, the application need to be modified/ re-written to populate the
dismembered EMP table pieces across the schemas / databases.
No select privileges be granted to schema owners scott, bruce, tom and harry on others’ schema tables.
Only the view_admin user can access the tables in scott, tom, bruce and harry’s schemas to create the
required row level / column level view.
Do not allow any users to login as the view_admin user. Only users, who are granted select privileges on
the custom built view are allowed to login to the database.
Everything has got its merits and demerits. You keep everything in one box. The hackers’ job is made easy.
You take extra care and distribute the data, at least all is not lost.
You can further complicate the security model and implement more levels and masking with synonyms and
making the access more complicated with grants and profiles.
Imagine my architecture
STAGE03 PUBLIC Synonym EMPLOYEE
STAGE02 View JP.N101_J102_T103_S_104_VIEW
STAGE01
scott.n101@dallas harry.j102@cleveland bruce.t103@buffalo tom.s104@austin
STAGE02 – all the user logins as VIEW_ADMIN are blocked. Unless someone connects as sys or system
and obtains the view definition for all my important tables, data is not lost. Such an occurrence is very
remote. I am auditing all users accessing secure and confidential data.
STAGE03 – all users with select permission on the view can access his or her own data from the view.
Don’t you think this data model is secure and safe from unauthorized access and hackers.