Изучаем метки доступа к строкам в Oracle: примеры не самого очевидного поведения защитыВладимир Пржиялковский
СодержаниеАннотацияЭта статья является непосредственным продолжением статьи Изучаем метки доступа к строкам в Oracle: задание свойств столбца доступа в таблице, и рассматривает примеры поведения средства Label Security в Oracle, не являющиеся очевидными для неспециалиста по мандатному доступу к данным. Показана возможность страховать пользователя от непредусмотренных для его уровня секретности действий и неочевидная особенность выдачи пользователю засекреченных данных. Подразумеваемые в статье состояние базы и сценарные файлы соответствуют концу предыдущей статьи. Не только защита строк, но и страховка пользователейОдна из интересных особенностей меточного ("мандатного") доступа в том, что он позволяет обладателю определенного уровня доступа запретить правку строк, не только более секретных, чем ему положено, но также и строк, менее секретных. Это напоминает кастовость по части действия; так сказать, "что положено быку, нельзя делать Юпитеру". В Oracle Label Security эта особенность нашла воплощение, в чем легко убедиться. Создадим нового пользователя и дадим ему полномочия работы исключительно с "секретными" строками: CONNECT / AS SYSDBA CREATE USER secretmanager IDENTIFIED BY secretmanager; GRANT minimal TO secretmanager; CONNECT lbacsys/lbacsys BEGIN 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
14 rows selected. SQL> @updateallenpnumber SQL> @updateallen OPEN SQL> @updateallen LIMITED Невозможно поменять ни "основную" строку для Аллена, ни метку доступа к его телефону. Обратите внимание: несмотря на это пользователю SECRETMANAGER видны все строки - как помеченные более слабой меткой OPEN, так и помеченные меткой LIMITED. А теперь переведем телефон Аллена из категории OPEN в категорию LIMITED и понаблюдаем, что он может делать со строкой "своей" категории секретности: SQL> CONNECT head/head 1 row updated. SQL> CONNECT secretmanager/secretmanager 1 row updated. SQL> @updateallen LIMITED 1 row updated. SQL> @updateallen OPEN 1 row updated. SQL> @updateallen OPEN Очевидно, пользователь может читать как "свои" строки, так и менее секретные, а вот изменять менее секретные, чем ему положено, строки он не сможет. В приведенном примере тайный 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
15 rows selected. SQL> CONNECT employee/employee
9 rows selected. Меточный доступ в Oracle справедливо показал пользователю EMPLOYEE имя Аллена (его строка в таблице EMP в открытом доступе), и не показал его телефоны (мы закрыли доступ к телефонам Аллена в таблице PHONE), но вот только открытое соединение таблиц EMP и PHONE показало "отсутствие" (на деле - недоступность) телефона одной строкой, а не двумя ! Ничего лишнего: телефон недоступен, а сколько их недоступно - не сообщается. Если же сделать один из телефонов Аллена открытым, информация о наличии второго, недоступного телефона и вовсе пропадет: SQL> CONNECT head/head 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
9 rows selected. Не думаю, что такое поведение для всех очевидно, а значит приведенные выше примеры могут оказаться небесполезными. Ссылки по теме |