Владимир Пржиялковский
Аннотация
Эта статья
рассматривает некоторые особенности средства Label Security в
Oracle. Здесь показана возможность секретить служебный столбец с
метками доступа к строкам, а также рассмотрены некоторые правила
правки меток. В первую очередь статья затрагивает использование
параметра TABLE_OPTIONS процедуры APPLY_TABLE_POLICY из пакета
SA_POLICY_ADMIN.
Введение
Label
Security есть реализация фирмой Oracle меточного, или
мандатного метода доступа, известного специалистам по защите
данных. Описание Label Security в документации Oracle имеет
характерный справочный характер, что в данном случае можно считать
обоснованным, так как самый мандатный доступ не придуман фирмой
(аналогично тому, как фирма Oracle не придумала SQL или, скажем,
JDBC). В то же время описание мандатного доступа, на которое
ссылается фирма Oracle, http://niap.nist.gov/cc-scheme/cc_docs/, весьма
непросто для восприятия специалистом по БД. Несколько более понятны
тексты на русском языке, подготовленные Гостехкомиссией при Президенте РФ, однако и они
рассчитаны в первую очередь на специалистов по безопасности.
Настоящая работа предназначена показать некоторые возможности
Label Security именно администраторам и разработчикам на Oracle, а
главное - помочь им в самостоятельном изучении этой темы. Без
последнего, увы, не обойтись: даже выборочное рассмотрение меточного
доступа на простых примерах потребовало сразу серии статей !
Здесь будет показана
возможность секретить служебный столбец с метками доступа к строкам,
а также рассмотрены некоторые возможности правки конкретных меток. В
первую очередь статья сосредотачивается на использовании параметра
TABLE_OPTIONS процедуры APPLY_TABLE_POLICY из пакета
SA_POLICY_ADMIN.
Подготовка к работе
Предполагается, что имеются структуры и объекты, а
именно:
- первоначально отсутствовавшая в схеме SCOTT таблица PHONE,
заполненная номерами телефонов для сотрудников из таблицы EMP
- два уровня секретности с краткими названиями 'OPEN' и
'LIMITED'
- политика меточного доступа под названием EMPSEC_POLICY и
заданное в рамках этой политики название служебного столбца для
меток доступа под названием EMPSEC_LABEL
- две разные метки, построенные на базе имеющихся уровней
секретности, и которыми в рамках политики EMPSEC_POLICY помечены
строки таблиц PHONE и EMP схемы SCOTT
- два пользователя EMPLOYEE и HEAD, отмеченные разными правами
доступа к строкам
Чтобы все это построить в своей БД, достаточно шаг за шагом
повторить действия из предыдущей статьи.
Для удобства работы в SQL*Plus подготовим несколько
файлов. Файл phonepolicyoptions.sql:
CONNECT lbacsys/lbacsys
BEGIN
SA_POLICY_ADMIN.REMOVE_TABLE_POLICY
(
POLICY_NAME => 'empsec_policy'
, SCHEMA_NAME => 'scott'
, TABLE_NAME => 'phone'
, DROP_COLUMN => TRUE
);
END;
/
BEGIN
SA_POLICY_ADMIN.APPLY_TABLE_POLICY
(
POLICY_NAME => 'empsec_policy'
, SCHEMA_NAME => 'scott'
, TABLE_NAME => 'phone'
, TABLE_OPTIONS => '&1'
);
END;
/
UPDATE scott.phone
SET empsec_label
= CASE
WHEN empno IN (
SELECT empno
FROM scott.emp
WHERE job IN ( 'MANAGER', 'PRESIDENT' )
)
THEN CHAR_TO_LABEL ( 'EMPSEC_POLICY', 'LIMITED' )
ELSE CHAR_TO_LABEL ( 'EMPSEC_POLICY', 'OPEN' )
END
;
В этом сценарии сначала из политики EMPSEC_POLICY исключается
таблица SCOTT.PHONE, причем благодаря явно указанному значению
параметра DROP_COLUMN => TRUE служебный (в рамках этой политики)
столбец EMPSEC_LABEL также удалится. Затем политика применяется к
таблице заново, а ее (новые, те, что нам требуется) свойства будем
указывать через параметр для SQL*Plus. Поскольку служебный
столбец в таблице PHONE воссоздается заново, его придется и заново
заполнять, причем (обратите внимание !) ради удобства всегда
однаково.
Другой файл, phones.sql, послужит для наблюдения
результата:
SELECT ename, pno
FROM scott.emp LEFT OUTER JOIN scott.phone
USING (empno)
/
Он взят из предыдущей статьи, но в силу своей краткости и ради
ясности повторяется здесь.
Создадим также файл updateallen.sql:
UPDATE scott.phone
SET
empsec_label
= CHAR_TO_LABEL ( 'empsec_policy', '&1' )
WHERE
empno
= ( SELECT empno FROM scott.emp WHERE ename = 'ALLEN' )
/
Несколько прочих сценарных файлов будет создано по ходу дела.
Выдадим в SQL*Plus:
SQL> SET VERIFY OFF
Можно ставить опыты.
Исчезающий столбец
В предыдущей статье оговаривалось, что служебный столбец,
добавленный в результате применения политики к таблице, можно скрыть
от пользователей. Покажем, как это сделать. Выдадим в
SQL*Plus:
@phonepolicyoptions 'read_control, hide'
Проверка:
SQL> COLUMN POLICY_NAME FORMAT A22
SQL> COLUMN SCHEMA_NAME FORMAT A12
SQL> COLUMN TABLE_NAME FORMAT A12
SQL> COLUMN TABLE_OPTIONS FORMAT A15 WORD
SQL> SELECT policy_name, schema_name, table_name, table_options
2 FROM dba_sa_table_policies;
POLICY_NAME SCHEMA_NAME TABLE_NAME TABLE_OPTIONS
---------------------- ------------ ------------ --------------
EMPSEC_POLICY SCOTT EMP READ_CONTROL,
LABEL_DEFAULT
EMPSEC_POLICY SCOTT PHONE READ_CONTROL,
HIDE
SQL> SAVE showoptions
Создано file showoptions.sql
SQL> CONNECT employee/employee
Соединено.
SQL> SELECT column_name FROM all_tab_columns
2 WHERE owner = 'SCOTT' AND table_name = 'PHONE';
COLUMN_NAME
------------------------------
EMPNO
PNO
SQL> SAVE showcolumns
Создано file showcolumns.sql
SQL> CONNECT head/head
Соединено.
SQL> /
COLUMN_NAME
------------------------------
EMPNO
PNO
Обратите внимание: столбец EMPSEC_LABEL стал невидим, то есть ни
у хозяина таблицы, ни у пользователей не стало причин догадываться,
что им предъявляется только часть строк ! Дополнительной скрытности
добавляет то обстоятельство, что даже SYS не увидит скрытого столбца
(проверьте это !) А вот для сравнения, что будет, если свойство HIDE
«уберем» (то есть не укажем):
@phonepolicyoptions 'read_control'
Проверка:
SQL> CONNECT head/head
Соединено.
SQL> @showcolumns
COLUMN_NAME
------------------------------
EMPNO
PNO
EMPSEC_LABEL
Обратите внимание на то, что когда столбец EMPSEC_LABEL был
невидим, это обстоятельство не помешало администратору Label
Security (пользователю LBACSYS) обратиться к столбцу командой
UPDATE scott.phone SET empsec_label = ... в файле
phonepolicyoptions.sql.
Кто и как может изменять метки секретности
Умолчательная реакция на изменение метки обычным
пользователем
Метку секретности строки можно поменять, и администратор
(пользователь LBACSYS) это уже делал. А вот что произойдет, если
поменять значение метки попробуют «обычные» пользователи:
CONNECT / AS SYSDBA
GRANT INSERT, UPDATE, DELETE ON scott.phone TO minimal;
Проверка:
SQL> CONNECT head/head
Соединено.
SQL> @updateallen OPEN
1 строка обновлена.
SQL> @updateallen LIMITED
1 строка обновлена.
SQL> @updateallen LIMITED
1 строка обновлена.
SQL> @updateallen OPEN
1 строка обновлена.
Вывод: пользователь HEAD беспрепятственно изменяет метку строки,
как ему угодно. А пользователь EMPLOYEE ?
SQL> CONNECT employee/employee
Соединено.
SQL> @updateallen OPEN
1 строк обновлено.
SQL> @updateallen OPEN
1 строк обновлено.
SQL> @updateallen LIMITED
1 строк обновлено.
SQL> @updateallen LIMITED
0 строк обновлено.
SQL> @updateallen OPEN
0 строк обновлено.
Очевидно, как только метка становится LIMITED, пользователь
EMPLOYEE теряет возможность ее изменять, а когда значение метки -
OPEN, он такую возможность имеет. Он даже может сделать строку более
секретной, но тогда потеряет к ней доступ.
Запрет делать то, результат чего не увидишь
Ситуация напоминает выводимую таблицу, view, где обладатель права
изменять view может добавить через view в базовую таблицу строки,
которые сам через view не увидит. Воспрепятствовать этому способно
специальное ограничение целостности WITH CHECK OPTION. А можно ли
здесь запретить выводить строки из зоны собственной видимости ? Да:
для этого в параметре TABLE_OPTIONS достаточно указать специальный
режим CHECK_CONTROL использования метки в таблице PHONE. Выдаем в
SQL*Plus:
@phonepolicyoptions 'read_control, check_control'
Проверка:
SQL> CONNECT employee/employee
Connected.
SQL> @updateallen OPEN
1 row updated.
SQL> @updateallen LIMITED
UPDATE scott.phone
*
ERROR at line 1:
ORA-28115: policy with check option violation
SQL> @updateallen OPEN
1 row updated.
В то же время пользователь HEAD, который «видит все», нового
ограничения не заметит:
SQL> CONNECT head/head
Connected.
SQL> @updateallen OPEN
1 row updated.
SQL> @updateallen LIMITED
1 row updated.
SQL> @updateallen LIMITED
1 row updated.
SQL> @updateallen OPEN
1 row updated.
Жесткий запрет на изменение метки
Другой режим использования метки в TABLE_OPTIONS еще более
ограничителен. Он вовсе запрещает изменять значение метки, не важно
в сторону ли увеличения или понижения ее секретности. Выдадим:
@phonepolicyoptions 'read_control, label_update'
Проверяем:
SQL> CONNECT employee/employee
Connected.
SQL> @updateallen OPEN
1 row updated.
SQL> @updateallen LIMITED
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
SQL> @updateallen OPEN
1 row updated.
SQL> CONNECT head/head
Connected.
SQL> @updateallen OPEN
1 row updated.
SQL> @updateallen LIMITED
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
Пример пока лишь доказывает, что метку нельзя сделать более
«секретной». Но возможно, разрешено «играть на понижение»
секретности ? Проверям снова:
CONNECT lbacsys/lbacsys
Connected.
SQL> @updateallen LIMITED
1 row updated.
SQL> CONNECT head/head
Connected.
SQL> @updateallen LIMITED
1 row updated.
SQL> @updateallen OPEN
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
Что и требовалось доказать: режим LABEL_UPDATE использования
метки, заданный для таблицы PHONE в рамках нашей политики, не
позволяет обычным пользователям изменять значение меток доступа в
строках таблицы.