Oracle SQL Firewall no Active Data Guard


Na palestra que fiz no GUOB Tech day 2026 uma das perguntas que recebi foi sobre a utilização do Oracle SQL Firewall no ambiente active data guard. 

De acordo com a documentação o SQL Firewall é uma solução de firewall simples e fácil de usar para todas as implementações do Oracle AI Database, como on-premises, nuvem, multitenant, oracle data guard ou Oracle RAC. Porém não há uma explicação como ele vai gerar a as violações que devem ser gravadas na dba_sql_firewall_violations, uma vez que o active data guard está em leitura.

Para validar essa questão, montei um ambiente com o oracle data guard e SQL Firewall para testar como funcionaria quando ocorresse uma violação. 

Status do data guard:

Connected to:
Oracle AI Database 26ai Enterprise Edition Release 23.26.3.0.0 - Production
Version 23.26.3.0.0

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORA26AI_PDB1                   READ ONLY  NO
SQL>
SQL> SQL> SELECT db_unique_name, database_role, open_mode FROM v$database; 2 3 4 5 DB_UNIQUE_NAME DATABASE_ROLE OPEN_MODE ------------------------------ ---------------- -------------------- ora26ai_5sz_vcp PRIMARY READ WRITE

Para validar o comportamento do SQL Firewall nesse ambiente, conectamos com um usuário de teste e executamos duas consultas. A primeira não estava autorizada pela política ativa e, por isso, foi bloqueada pelo banco de dados com o erro ORA-47605: SQL Firewall violation. Em seguida, executamos uma consulta previamente registrada na allow-list, que foi processada normalmente. O teste demonstra que o SQL Firewall continua aplicando a política no ambiente Data Guard, bloqueando comandos não autorizados sem impedir a execução das operações legítimas.

[oracle@oracle26ai ~]$
[oracle@oracle26ai ~]$ sqlplus FW_DEMO_APP/<SENHA>@ora26aidg

SQL*Plus: Release 23.26.1.0.0 - Production on Wed Sep 2 22:48:46 2026
Version 23.26.1.0.0

Copyright (c) 1982, 2025, Oracle.  All rights reserved.

Last Successful login time: Wed Sep 02 2026 22:28:54 +00:00

Connected to:
Oracle AI Database 26ai Enterprise Edition Release 23.26.3.0.0 - Production
Version 23.26.3.0.0

SQL> select count(1) from HISTORICO_SALARIAL;
select count(1) from HISTORICO_SALARIAL
                     *
ERROR at line 1:
ORA-47605: SQL Firewall violation
Help: https://docs.oracle.com/error-help/db/ora-47605/


SQL> select tname from tab;

TNAME
--------------------------------------------------------------------------------
DEPARTAMENTOS
CARGOS
FUNCIONARIOS
HISTORICO_SALARIAL

SQL>

Agora vou consultar a dba_sql_firewall_violations para validar se ocorreu o registro de dessa violação uma vez que o banco esta em modo leitura no data guard. 

Connected to:
Oracle AI Database 26ai Enterprise Edition Release 23.26.3.0.0 - Production
Version 23.26.3.0.0

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORA26AI_PDB1                   READ ONLY  NO
SQL> alter session set container=ORA26AI_PDB1;

Session altered.

SQL> SELECT *
FROM   dba_sql_firewall_violations
WHERE  username = 'FW_DEMO_APP'
AND occurred_at > SYSDATE -2
ORDER  BY occurred_at DESC;  2    3    4    5

no rows selected

SQL>
SQL> EXEC DBMS_SQL_FIREWALL.FLUSH_LOGS; BEGIN DBMS_SQL_FIREWALL.FLUSH_LOGS; END; * ERROR at line 1: ORA-16000: Attempting to modify database or pluggable database that is open for read-only access. ORA-06512: at "SYS.DBMS_SQL_FIREWALL", line 94 ORA-06512: at line 1 Help: https://docs.oracle.com/error-help/db/ora-16000/

O teste demonstrou que o enforcement do SQL Firewall funciona normalmente no active data guard, bloqueando comandos não autorizados com o erro ORA-47605. Entretanto, as violações geradas localmente no standby não são persistidas na DBA_SQL_FIREWALL_VIOLATIONS, pois o mecanismo nativo depende da gravação dos logs em tabelas internas e o PDB está aberta somente para leitura. Essa limitação é confirmada pelo erro ORA-16000 ao executar DBMS_SQL_FIREWALL.FLUSH_LOGS.

Então como eu posso registrar as violações quando minhas consultas estão rodando no active data guard?

Para garantir o registro das violações executadas no standby, deve-se habilitar a unified auditing. Nesse caso, os eventos são gravados em arquivos externos de spillover e disponibilizados pela UNIFIED_AUDIT_TRAIL, permitindo identificar o standby responsável por meio da coluna DB_UNIQUE_NAME.

Para o standby, utilize o Unified Auditing. A política deve ser criada no primary:

Oracle AI Database 26ai Enterprise Edition Release 23.26.1.0.0 - Production
Version 23.26.1.0.0

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORA26AI_PDB1                   READ WRITE NO
SQL>
SQL> alter session set container=ORA26AI_PDB1;

Session altered.

SQL> CREATE AUDIT POLICY sql_firewall_fw_demo
    ACTIONS COMPONENT = SQL_FIREWALL ALL
    ON FW_DEMO_APP;  2    3

Audit policy created.

SQL> AUDIT POLICY sql_firewall_fw_demo;

Audit succeeded.

SQL> col POLICY_NAME for a25
SQL> col ENTITY_NAME for a25
SQL> SELECT
    policy_name,
    enabled_option,
    entity_name,
    entity_type
FROM audit_unified_enabled_policies
WHERE policy_name = 'SQL_FIREWALL_FW_DEMO';  2    3    4    5    6    7

POLICY_NAME               ENABLED_OPTION  ENTITY_NAME               ENTITY_
------------------------- --------------- ------------------------- -------
SQL_FIREWALL_FW_DEMO      BY USER         ALL USERS                 USER

SQL>

Depois de aguardar a aplicação do redo no standby, vou realizar uma nova consulta que violará a politica do SQL Firewall e validar os registros da unified auditing.

SQL> set lines 260
SQL> col SQL_TEXT for a90
col DB_UNIQUE_NAME for a25
SQL> SQL> col DBUSERNAME for a15
SQL> col CLIENT_PROGRAM_NAME for a30
SQL> col FW_ACTION_NAME for a15
col EVENT_TIMESTAMP for a30

SELECT
    db_unique_name,
    dbusername,
    fw_action_name,
    fw_return_code,
SQL> SQL> SQL>   2    3    4    5    6      client_program_name,
        event_timestamp,
    sql_text
FROM unified_audit_trail
  7    8    9   10  WHERE audit_type = 'SQL Firewall'
  AND dbusername = 'FW_DEMO_APP'
ORDER BY event_timestamp DESC; 11   12

DB_UNIQUE_NAME            DBUSERNAME      FW_ACTION_NAME  FW_RETURN_CODE CLIENT_PROGRAM_NAME            EVENT_TIMESTAMP                SQL_TEXT
------------------------- --------------- --------------- -------------- ------------------------------ ------------------------------ ------------------------------------------------------------------------------------------
ora26ai_j4j_vcp           FW_DEMO_APP     SQL Violation            47605 sqlplus@oracle26ai (TNS V1-V3) 02-SEP-26 11.16.26.883185 PM   select count(1) from HISTORICO_SALARIAL
ora26ai_j4j_vcp           FW_DEMO_APP     SQL Violation            47605 sqlplus@oracle26ai (TNS V1-V3) 02-SEP-26 11.16.17.544783 PM   SELECT DECODE(USER, 'XS$NULL',  XS_SYS_CONTEXT('XS$SESSION','USERNAME'), USER) F

SQL>

No Active Data Guard, oa unified auditing não tenta escrever na tabela AUDSYS.AUD$UNIFIED. Ele grava o evento em arquivos externos de spillover .BIN, os quais são apresentados pela UNIFIED_AUDIT_TRAIL.

Conclusão

O teste demonstrou que o enforcement do SQL Firewall funciona normalmente no Active Data Guard, bloqueando comandos não autorizados com o erro ORA-47605. Entretanto, as violações geradas localmente no standby não são persistidas na DBA_SQL_FIREWALL_VIOLATIONS, pois o mecanismo nativo depende da gravação dos logs em tabelas internas e a PDB está aberto somente para leitura. 

Para registrar de forma persistente as violações ocorridas no standby, deve-se utilizar o Unified Auditing, que armazena os eventos em arquivos externos.

Outro ponto importante é que o SQL Firewall não permite manter diferentes níveis de enforcement no primary e no Active Data Guard para o mesmo usuário. Se o standby executar consultas de relatórios diferentes da carga transacional, esses comandos também precisarão fazer parte da allow-list. Uma alternativa mais segura é utilizar uma conta exclusiva para os relatórios executados no standby.

Comentários