Декабрь 2005

Владимир Пржиялковский,
Преподаватель технологий Oracle
www.ccas.ru/prz/

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


Источник: Море(!) аналитической информации ! ::
CITFORUM.RU, 2005 г.
http://citforum.ru/database/oracle/LearnOLS4/

"Наступила темнота,
Не ходи за ворота:
Кто на улицу попал -
Заблудился и пропал."

Корней Чуковский,«Краденое солнце»

"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»

Аннотация

Эта статья является непосредственным продолжением статьи «Изучаем метки доступа к строкам: правка обычных столбцов таблицы», и рассматривает примеры поведения средства 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      665-7282
ALLEN      882-3154
WARD       610-1718
JONES      100-6539
MARTIN     103-1983
BLAKE      193-3112
CLARK      310-2673
SCOTT      680-4853
KING       542-6672
TURNER     293-1398
ADAMS      278-5105
JAMES      932-6728
FORD       485-9127
MILLER     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      665-7282
ALLEN      111-2222
ALLEN      882-3154
WARD       610-1718
JONES      100-6539
MARTIN     103-1983
BLAKE      193-3112
CLARK      310-2673
SCOTT      680-4853
KING       542-6672
TURNER     293-1398
ADAMS      278-5105
JAMES      932-6728
FORD       485-9127
MILLER     865-6706

15 rows selected.

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

ENAME      PNO
---------- --------------------
ALLEN
WARD       610-1718
MARTIN     103-1983
BLAKE
CLARK
KING
TURNER     293-1398
JAMES      932-6728
MILLER     865-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
---------- --------------------
ALLEN      111-2222
WARD       610-1718
MARTIN     103-1983
BLAKE
CLARK
KING
TURNER     293-1398
JAMES      932-6728
MILLER     865-6706

9 rows selected.

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

E-mail this page