В этой части мы рассмотрим расширенные концепции FGA, такие, как модель пользователей приложения и реконструкция данных, которые просматривал пользователь.
В предшествующей статье объяснялось, как настроить FGA, чтобы записать в таблицу FGA_LOG$ данные о пользователях базы данных, которые выполняли запросы. Этот подход работает хорошо в тех случаях, когда пользователь базы данных соответствует одному-единственному физическому пользователю. Однако в некоторых случаях, например, с веб-приложениями, сервер приложений соединяется с базой данных, используя неизменный пользовательский идентификатор, скажем, APPUSER. Пользователи приложения аутентифицируются приложением. Например, пользователь SCOTT соединяется с приложением, которое аутентифицирует его, а затем оно соединяется с базой данных, используя идентификатор пользователя APPUSER. Если средства FGA будут использоваться в такой среде, то они будут показывать пользователя APPUSER, а не SCOTT. Точно так же и другой пользователь приложения JANE, выбирающий данные, будет также регистрироваться как пользователь APPUSER, а не JANE. Поскольку зарегистрированное в журнале аудита имя пользователя не является именем фактического пользователя, цели аудита не будут достигнуты.
Первое решение, которое приходит на ум, состоит в том, чтобы создать пользователей приложений в базе данных, позволяя приложению соединяться с базой данных, используя те же идентификаторы пользователей и пароли. Скажем, в вышеприведенном примере пользователи SCOTT и JANE будут пользователями базы данных и не будет никакой потребности иметь пользователя по имени APPUSER. Этот подход прост и безопасен, поскольку пользователь аутентифицируется сервером базы данных, и имя пользователя остается тем же самым независимо от способа подключения.
При таком подходе, однако, все пользователи должны быть созданы в базе данных, что приведет к кошмару администрирования, особенно когда число пользователей достигнет нескольких тысяч, что является обычным в веб-приложениях. Кроме того, пользователи должны запоминать свои имена пользователей и пароли в различных местах; неудобство, которое полностью оправдает существование опции однократной регистрации (SSO, Single Sign-On). Хотя эта проблема может быть решена при использовании опции расширенной безопасности (ASO, Oracle Advanced Security Option), также известной как расширенная сетевая опция (ANO, Advanced Networking Option) наряду с использованием интернет-каталога Oracle (OID, Oracle Internet Directory), для большинства сайтов это решение не подходит.
В веб-приложениях в концепции пула соединений (connection pooling) также требуется использование одного универсального идентификатора пользователя. Как показано на следующем рисунке, сервер приложений создает несколько соединений с базой данных, используя пользователя APPUSER. Когда пользователю приложения, такому, как SCOTT, требуется обслуживание, относящееся к базе данных, приложение для выполнения запроса использует одно из этих соединений с базой данных. Эта модель может поддерживать много пользователей, используя только несколько соединений и, следовательно, находит поддержку у архитекторов веб-приложений. Но снова этот подход не позволяет FGA записать правильное имя пользователя.
Database Sessions – сеансы базы данных.
Аргументы в пользу универсальных идентификаторов пользователей приложений очень сильны. Таким образом, предпочтительнее не пытаться "избавиться" от этого требования, идеальное решение состоит в том, чтобы использовать в среде FGA идентификаторы пользователей приложений.
Идентификатор клиента
В СУБД Oracle9i введено понятие идентификатора клиента (client identifier), который является значением, устанавливаемым в качестве атрибута сеанса. Все, что находится в этом атрибуте, в нашей ситуации мы можем использовать для представления имени фактического пользователя, такого, как JANE. И даже если имя пользователя базы данных зарегистрировано как APPUSER или что-то подобное, идентификатор клиента может иметь значение JANE.
Вы можете установить значение идентификатора клиента для сеанса с помощью поставляемой корпорацией Oracle пакетной процедуры dbms_session.set_identifier. Следующий оператор устанавливает в сеансе идентификатор SCOTT:
EXECUTE DBMS_SESSION.SET_IDENTIFIER ('SCOTT')
После установки этот идентификатор виден для данного сеанса в представлении V$SESSION:
SELECT CLIENT_IDENTIFIER
FROM V$SESSION
WHERE AUDSID = USERENV('SESSIONID');
Здесь будет показано значение SCOTT, которое и было установлено ранее. Итак, какова важность этого значения? В дополнение к тому, что эта информация находится в представлении V$SESSION, она также обнаруживается в среде FGA в таблице FGA_LOG$ и, впоследствии, в представлении DBA_FGA_AUDIT_TRAIL в столбце CLIENT_ID, как показано ниже:
SELECT DB_USER, CLIENT_ID FROM DBA_FGA_AUDIT_TRAIL;
И даже если столбец DB_USER показывает пользователя базы данных, в журнале аудита FGA может быть найден реальный пользователь приложения, если его имя установлено в идентификаторе клиента. Это очень важно для понимания и применения во время аудита пользователей приложения.
Идентификатор клиента также находится в журнале обычного аудита, а не только в журнале детального аудита. Итак, во всех типах аудита, от обычного до расширенного детального, это значение обеспечивает недостающую связь для представления фактического пользователя. В случае обычного аудита идентификатор клиента, если он установлен в сеансе, записывается в таблицу AUD$ в столбец CLIENTID. Это значение находится в зависимых представлениях, таких, как DBA_AUDIT_TRAIL, в столбце CLIENT_ID.
Проблема: как установить это значение должным образом. Помните, в веб-приложениях пул соединений сеансы базы данных обслуживают много пользовательских сеансов, а значит, установка идентификатора только один раз в начале сеанса не поможет. Вместо этого приложение должно устанавливать идентификатор клиента перед каждым обращением к базе данных, чтобы средства FGA могли видеть фактический идентификатор пользователя приложения. Когда сеанс базы данных повторно используется другим потоком приложения, в идентификатор клиента вводится идентификатор данного пользователя, что позволяет "опознать" его в журнале аудита FGA.
Другой подход состоит в том, чтобы создать "куку" (cookie) и использовать это значение для установки идентификатора клиента. Этот способ более безопасен, поскольку "кука" может содержать другую аутентификационную информацию, которая не доступна в обычном сеансе. Значение в идентификаторе в этом случае может быть должным образом декодировано для получения реального имени пользователя, но аутентификационная информация добавляет к значению идентификатора клиента компонент целостности данных.
Контексты приложений
Использование идентификатора клиента имеет свои преимущества, но также и представляет серьезную угрозу безопасности: эта установка предполагает, что пользователь установит в идентификаторе значение реального идентификатора пользователя, но этого нельзя гарантировать. Злонамеренный пользователь может соединиться с базой данных и установить значение другого идентификатора пользователя, что серьезно подрывает достоверность журнала аудита. В веб-приложениях использование "куков" для хранения идентификаторов клиентов делает эту задачу трудной, если не невозможной; но в обычных приложениях использование только клиентских идентификаторов не обеспечивает удовлетворительной защиты. Нам требуется более безопасное средство фиксации пользователей приложения в журнале аудита.
Предложим решение: контексты приложений (application contexts). Контексты приложений похожи на атрибуты сеанса: после установки к ним можно обращаться в сеансе в любое время. В другом сеансе может быть установлено другое значение, но эти значения не будут видны в других сеансах. Контекст имеет атрибуты, подобные столбцам таблицы; но, в отличие от таблиц, контексты – не объекты сегментов, и атрибуты могут быть определены во время выполнения, а не во время проектирования.
Контекст приложения может быть создан следующим SQL-оператором:
create context my_app_ctx using set_my_app_ctx;
Обратите внимание на предложение using set_my_app_ctx, указывающее, что атрибутами внутри контекста можно манипулировать только с помощью процедуры с именем set_my_app_ctx, определяемой следующим образом:
create or replace procedure set_my_app_ctx
(
p_app_user in varchar2 := USER
)
is
begin
dbms_session.set_context('MY_APP_CTX','APP_USERID', p_app_user);
end;
Эта процедура просто устанавливает в атрибуте APP_USERID значение, передаваемое в ее входном параметре, вызывая для этой установки процедуру dbms_session.set_context. Что случится, если пользователь непосредственно вызовет процедуру dbms_session.set_context?
SQL> exec dbms_session.set_context('MY_APP_CTX','APP_USERID', 'JUNE')
BEGIN dbms_session.set_context('MY_APP_CTX','APP_USERID', 'JUNE'); END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 78
ORA-06512: at line 1
Обратите внимание на ошибку ORA-01031:insufficient privileges (недостаточные привилегии), которая в данное время немного вводит в заблуждение. Пользователь не имеет привилегии выполнения процедуры SYS.DBMS_SESSION, установка атрибута контекста вызовом этой процедуры запрещена, поэтому возникает ошибка. Однако когда пользователь для установки атрибута вызовет доверенную процедуру:
SQL> execute set_my_app_ctx ('AAAA')
PL/SQL procedure successfully completed.
…она выполнится успешно. Атрибуты контекста могут устанавливаться только с помощью этой процедуры, поэтому она и называется соответствующим образом – доверенная процедура (trusted procedure). Это важное свойство контекста приложения, и оно может использоваться в FGA.
Атрибут контекста, если установлен (в приведенном выше коде), может быть извлечен вызовом функции SYS_CONTEXT:
select sys_context('MY_APP_CTX','APP_USERID') from dual;
Этот оператор возвращает значение атрибута. Если контекст может быть установлен безопасным способом, его можно использовать для установки идентификатора клиента.
Исходя из наших знаний, возможное решение может выглядеть следующим образом:
- приложение выполняет процедуру, которая автоматически устанавливает правильное значение в контексте приложения. В вышеупомянутом примере атрибут контекста использовался для установки идентификатора пользователя, но можно также использовать и другой атрибут, такой, как роль пользователя. В контексте вы можете определять более одного атрибута. Атрибут может использоваться как включаемая роль. В доверенную процедуру можно включить все типы проверок безопасности, обеспечивая защиту и аутентичность. Если эти проверки безопасности будут неудачными, требуемая роль не будет включена. Так, даже если пользователь может успешно соединиться с базой данных, используя учетную запись APPUSER, он будет не в состоянии манипулировать данными, так как соответствующая роль не будет включена. Обратите внимание: роли должны быть ролями, аутентифицируемыми процедурой, а не обычными. Такие роли создаются оператором CREATE ROLE <имя_роли> USING <имя_процедуры>; и пользователь включает роль, вызывая <имя_процедуры>, а не оператором SET ROLE;
- эта процедура также устанавливает идентификатор клиента, так что нет никакой потребности предоставлять привилегии выполнения пакета dbms_session всем пользователям (public), они не нужны даже данному пользователю. Поскольку пользователи не имеют привилегий вызова процедур пакета dbms_session, они не могут непосредственно устанавливать идентификаторы клиентов – те будут устанавливаться и переноситься в журнал детального аудита автоматически.
Этот метод может быть в дальнейшем усовершенствован за счет использования определяемых пользователем записей аудита, в которых в идентификаторах клиентов могут устанавливаться значения, извлекаемые из контекста приложения. Мы обсудим данный метод в третьей (и последней) части этой серии статей.
Что видел пользователь?
В журнале детального аудита регистрируются фактические операторы, введенные пользователем, вместе со значениями переменных связывания, если они использовались. Типичный оператор, который мог быть записан в журнал аудита:
select balance from accounts
where acct_no = 10034;
Скажем, эта транзакция была выполнена утром в 10:00, а сейчас – 11:00, в это время остаток на счете, возможно, уже был изменен. Если аудитор (или администратор базы данных) решает увидеть точно то, что пользователь действительно видел в то время, существующее значение столбца, возможно, уже не показывает точную информацию. В случаях промышленного шпионажа или для установления повода или профиля необходимы точные данные, просмотренные пользователем. Даже если средства FGA не зафиксировали точные данные на тот момент времени, мы можем увидеть их, используя другую информацию, зафиксированную в журнале аудита.
В части 1 этой серии статей вы видели структуру представления DBA_FGA_AUDIT_TRAIL, в которой имеется несколько ключевых столбцов, связанных с сеансом и пользователем. Подходящий столбец здесь – SCN, в котором содержится системный номер изменения (SCN, System Change Number) на момент времени генерации записи аудита. Используя ретроспективный запрос (flashback query), мы можем реконструировать данные на тот момент времени. Предполагая, что значение SCN в журнале аудита было равно 123456, мы можем выполнить следующий запрос:
select balance from accounts as of SCN 123456
where acct_no = 10034;
Предложение as of SCN 123456 позволяет получить из таблицы остаток на счете, который был в нужный нам момент времени.
Поскольку ретроспективный запрос ограничен периодом сохранения информации в пространстве отката (undo retention period), транзакции, которые были выполнены за пределами этого периода, будут потеряны для анализа. Однако аудиторы могут анализировать записи аудита, сгенерированные после данного события аудита, используя ретроспективные запросы только для выборки из важных столбцов.
В следующий раз
В части 3 этой серии статей мы будем обсуждать определяемые пользователями средства FGA и новые захватывающие функциональные возможности FGA в сервере Oracle Database 10g.
Часть 1 Часть 3
Арап Нанда (Arup Nanda) (arup@proligence.com) - основатель компании Proligence (Нью-Йорк), предоставляющей высокоспециализированную расширенную поддержку решений Oracle и обучение методам обеспечения информационной безопасности. В 2003 г. он был удостоен награды "Oracle's DBA of the Year"( администратор года баз данных Oracle). Арап - соавтор книги Oracle Privacy Security Auditing (издательство Rampant TechPress, 2003) - "Средства аудита в СУБД Oracle, обеспечивающие информационную безопасность".