Вы находитесь на страницах старой версии сайта.
Переходите на новую версию Interface.Ru

Изучаем метки доступа к строкам в Oracle: примеры не самого очевидного поведения защиты

Предыдущая статья серии

© Владимир Пржиялковский,
координатор Евро-Азиатской Группы Пользователей Oracle,
преподаватель УКЦ Interface Ltd.

"Наступила темнота,
Не ходи за ворота:
Кто на улицу попал -
Заблудился и пропал".
Корней Чуковский, "Краденое солнце"
 
"And neither the angels in heaven above,
Nor the demons down under the sea,
Can ever dissever my soul from the soul
Of the beautiful Annabel Lee …"
Edgar Allan Poe, "Annabel Lee"

 

 

 

 

 

 

 

Содержание

Аннотация

Эта статья является непосредственным продолжением статьи Изучаем метки доступа к строкам в Oracle: задание свойств столбца доступа в таблице, и рассматривает примеры поведения средства Label Security в Oracle, не являющиеся очевидными для неспециалиста по мандатному доступу к данным. Показана возможность страховать пользователя от непредусмотренных для его уровня секретности действий и неочевидная особенность выдачи пользователю засекреченных данных.

Подразумеваемые в статье состояние базы и сценарные файлы соответствуют концу предыдущей статьи.

Не только защита строк, но и страховка пользователей

Одна из интересных особенностей меточного ("мандатного") доступа в том, что он позволяет обладателю определенного уровня доступа запретить правку строк, не только более секретных, чем ему положено, но также и строк, менее секретных. Это напоминает кастовость по части действия; так сказать, "что положено быку, нельзя делать Юпитеру". В Oracle Label Security эта особенность нашла воплощение, в чем легко убедиться.

Создадим нового пользователя и дадим ему полномочия работы исключительно с "секретными" строками:

CONNECT / AS SYSDBA

CREATE USER secretmanager IDENTIFIED BY secretmanager;

GRANT minimal TO secretmanager;

CONNECT lbacsys/lbacsys

BEGIN
SA_USER_ADMIN.SET_USER_LABELS
(

POLICY_NAME        =>  'empsec_policy'
,USER_NAME         =>  'secretmanager'
,MAX_READ_LABEL    =>  'limited'
, MIN_WRITE_LABEL  =>  'limited'
);
END;
/

(Заметьте, что ранее параметр MIN_WRITE_LABEL в процедуре SET_USER_LABELS мы не использовали; в результате умолчательного поведения Label Security для пользователя HEAD было MIN_WRITE_LABEL = 'OPEN', что легко проверяется по справочным таблицам).

Проверим теперь возможности SECRETMANAGER по чтению и по изменению полей строк, в том числе поля метки:

SQL> CONNECT secretmanager/secretmanager
Connected.
SQL> @phones

ENAME PNO
---------- --------------------
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
665-7282
882-3154
610-1718
100-6539
103-1983
193-3112
310-2673
680-4853
542-6672
293-1398
278-5105
932-6728
485-9127
865-6706

14 rows selected.

SQL> @updateallenpnumber
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...

SQL> @updateallen OPEN
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...

SQL> @updateallen LIMITED
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...

Невозможно поменять ни "основную" строку для Аллена, ни метку доступа к его телефону. Обратите внимание: несмотря на это пользователю SECRETMANAGER видны все строки - как помеченные более слабой меткой OPEN, так и помеченные меткой LIMITED. А теперь переведем телефон Аллена из категории OPEN в категорию LIMITED и понаблюдаем, что он может делать со строкой "своей" категории секретности:

SQL> CONNECT head/head
Connected.
SQL> @updateallen LIMITED

1 row updated.

SQL> CONNECT secretmanager/secretmanager
Connected.
SQL> @updateallenpnumber

1 row updated.

SQL> @updateallen LIMITED

1 row updated.

SQL> @updateallen OPEN

1 row updated.

SQL> @updateallen OPEN
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...

Очевидно, пользователь может читать как "свои" строки, так и менее секретные, а вот изменять менее секретные, чем ему положено, строки он не сможет. В приведенном примере тайный SECRETMANAGER понизил секретность строки и потерял былую возможность строку править. Ну, а более секретные строки он даже не увидит !

Выдача данных: ничего лишнего?

В завершение знакомства с меточным доступом к строкам в Oracle мне хотелось бы подчеркнуть, что даже без учета структуры меток, привилегий, группирования пользователей и многого прочего, большая часть которого в этих статьях не рассматривалась, мандатный метод доступа не так прямолинеен в поведении, как мог бы показаться поначалу.

Рассмотрим обычную выдачу данных, помеченных метками доступа. Вспомним, что до сих пор в таблице PHONE у нас имелось по одному номеру телефона на каждого сотрудника. Попробуем добавить второй телефон Аллену, а так как сценарий phones.sql использует для выдачи на экран полуоткрытое соединение, употребление его останется корректным и для этих новых данных. Интерес представляет случай, когда телефоны Аллена (когда их станет два) будут иметь метку LIMITED, и когда к ним обратится пользователь EMPLOYEE. Интуиция подсказывает, что "невидимые" телефоны Аллена будут обрабатываться полуоткрытым соединением подобно пропущенному значению (NULL), и в результате выборки мы увидим несколько строк для Аллена с пропущенными значениями номеров телефона. А что на самом деле?

Добавим в таблицу PHONE для Аллена новый телефон и "засекретим" оба:

CONNECT head/head

INSERT INTO scott.phone

SELECT empno, '111-2222', empsec_label
FROM scott.phone
WHERE empno = (SELECT empno FROM scott.emp WHERE ename='ALLEN')

@updateallen LIMITED

Проверяем:

SQL> @phones

ENAME PNO
---------- --------------------
SMITH
ALLEN
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
665-7282
111-2222
882-3154
610-1718
100-6539
103-1983
193-3112
310-2673
680-4853
542-6672
293-1398
278-5105
932-6728
485-9127
865-6706

15 rows selected.

SQL> CONNECT employee/employee
Connected.
SQL> @phones

ENAME PNO
---------- --------------------
ALLEN 
WARD610-1718
MARTIN103-1983
BLAKE 
CLARK 
KING 
TURNER293-1398
JAMES932-6728
MILLER865-6706

9 rows selected.

Меточный доступ в Oracle справедливо показал пользователю EMPLOYEE имя Аллена (его строка в таблице EMP в открытом доступе), и не показал его телефоны (мы закрыли доступ к телефонам Аллена в таблице PHONE), но вот только открытое соединение таблиц EMP и PHONE показало "отсутствие" (на деле - недоступность) телефона одной строкой, а не двумя! Ничего лишнего: телефон недоступен, а сколько их недоступно - не сообщается. Если же сделать один из телефонов Аллена открытым, информация о наличии второго, недоступного телефона и вовсе пропадет:

SQL> CONNECT head/head
Connected.
SQL> UPDATE scott.phone

2  SET
3    empsec_label
4  = CHAR_TO_LABEL ( 'empsec_policy', 'OPEN' )
5  WHERE
6    pno = '111-2222'
7  /

1 row updated.

SQL> CONNECT employee/employee
Connected.
SQL> @phones

ENAME PNO
---------- --------------------
ALLEN111-2222
WARD610-1718
MARTIN103-1983
BLAKE 
CLARK 
KING 
TURNER293-1398
JAMES932-6728
MILLER865-6706

9 rows selected.

Не думаю, что такое поведение для всех очевидно, а значит приведенные выше примеры могут оказаться небесполезными.

Дополнительная информация

Обсудить на форуме Oracle

Рекомендовать страницу

INTERFACE Ltd.
Телефон/Факс: +7 (495) 925-0049
Отправить E-Mail
http://www.interface.ru
Rambler's Top100
Ваши замечания и предложения отправляйте редактору
По техническим вопросам обращайтесь к вебмастеру
Дата публикации: 12.09.05