Impacto do cursor_shring no Oracle SQL Firewall


Outra pergunta durante minha palestra sobre o Oracle SQL Firewall no Guob Tech Day 2026 foi sobre o comportamento do SQL firewall quando é feita uma alteração do parâmetro cursor_sharing.

A dúvida foi bastante válida uma vez que a utilização do parâmetro cursor_sharing para force, transforma os literais em binds geradas pelo Oracle. Isso força instruções que diferem apenas por literais a compartilharem exatamente o mesmo cursor e plano de execução.

De acordo com a documentação do Oracle 26ai o SQL Firewall:

  • captura o SQL antes das transformações internas;
  • normaliza as instruções capturadas;
  • substitui valores literais por símbolos especiais antes de armazená-las nos logs.

Como o SQL Firewall captura o SQL antes das transformações internas e realiza sua própria normalização, uma alteração de CURSOR_SHARING=EXACT para CURSOR_SHARING=FORCE não deveria, por si só, exigir a recriação da allowlist simplesmente por causa da substituição de literais

Para demonstrar de forma simples, será feito uma simulação alterando o parâmetro cursor_sharing de exat para force e validando o que foi coletado pelo sql firewall.

Primeiro, é criada a tabela CLIENTES com três registros. Em seguida, com o SQL Firewall em modo de captura para o usuário FW_DEMO_APP, é executada apenas a consulta:

SQL>
SQL> CREATE TABLE clientes (
    id   NUMBER PRIMARY KEY,
    nome VARCHAR2(100)
);  2    3    4

Table created.

SQL>
INSERT INTO clientes VALUES (10, 'Cliente 10');
INSERT INTO clientes VALUES (20, 'Cliente 20');
INSERT INTO clientes VALUES (30, 'Cliente 30');
COMMIT;SQL>
1 row created.

SQL>
1 row created.

SQL>
1 row created.

SQL>

Commit complete.

SQL>

Após a criação da tabela de teste, vamos será ativado o SQL, feita a captura de uma consulta nesta tabela e habilitado o sql firewall e gerada a allowlist.

--ATIVAR O SQL FIREWALL E INICIAR A CAPTURA PARA O USUÁRIO

SQL> set lines 210
SQL> SELECT * FROM clientes WHERE id = 10;

        ID NOME
---------- ----------------------------------------------------------------------------------------------------
        10 Cliente 10

Agora vamos validar o SQL  TEXT que foi registrado na nossa allowlist

SQL>
SQL> col SQL_TEXT for a90
SQL> SELECT
    sql_signature,
    sql_text
FROM dba_sql_firewall_allowed_sql
WHERE username = 'FW_DEMO_APP';  2    3    4    5

SQL_SIGNATURE                                                    SQL_TEXT
---------------------------------------------------------------- ------------------------------------------------------------------------------------------
015B2CC0B09F5571562AEA5F7F50500EAE600AA14624C8F0AA00FB504C7A11F2 SELECT * FROM CLIENTES WHERE ID=:"SYS_B_0"

SQL>

Vimos que o SQL firewall gravou a consulta utilizando uma bind no literal. Agora vamos executar uma consulta com um literal diferente da consulta realizada anteriormente.

SQL>
SQL> show parameter cursor_sharing;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT
SQL>
SQL> col SQL_TEXT for a90
SQL> SELECT
    sql_signature,
    sql_text
FROM dba_sql_firewall_allowed_sql
WHERE username = 'FW_DEMO_APP';  2    3    4    5

SQL_SIGNATURE                                                    SQL_TEXT
---------------------------------------------------------------- ------------------------------------------------------------------------------------------
015B2CC0B09F5571562AEA5F7F50500EAE600AA14624C8F0AA00FB504C7A11F2 SELECT * FROM CLIENTES WHERE ID=:"SYS_B_0"

SQL>

--MUDANDO O LITERAL DA CONSULTA

SQL>
SQL> SELECT * FROM clientes WHERE id = 20;

        ID NOME
---------- ----------------------------------------------------------------------------------------------------
        20 Cliente 20

SQL>

Por fim vamos alterar o parametro cursor_sharing de exact para force e executar uma terceira consulta passando um literal ainda não usado.

-- ALTERANDO O PARAMETRO CURSOR_SHARING PARA FORCE E EXECUTANDO UMA CONSULTA COM LITERAL DIFERENTE

SQL>
SQL> ALTER SESSION SET cursor_sharing = FORCE;

Session altered.

SQL>
SQL>
SQL> SELECT * FROM clientes WHERE id = 30;

        ID NOME
---------- ----------------------------------------------------------------------------------------------------
        30 Cliente 30

Conclusão

O teste demonstrou que o Oracle SQL Firewall realiza sua própria normalização das instruções SQL, independentemente do valor configurado em CURSOR_SHARING. Mesmo com CURSOR_SHARING=EXACT, a consulta capturada com ID = 10 foi armazenada na allowlist de forma normalizada e a execução posterior com ID = 20 foi permitida. Após alterar a sessão para CURSOR_SHARING=FORCE, a mesma estrutura utilizando ID = 30 também continuou sendo permitida.

Na prática, isso demonstra que alterar CURSOR_SHARING de EXACT para FORCE não exige, nesse cenário, uma nova entrada na allowlist simplesmente porque os valores literais mudaram. O SQL Firewall está interessado na estrutura normalizada do comando, enquanto CURSOR_SHARING está relacionado ao compartilhamento de cursores. Portanto, são mecanismos distintos, e o SQL Firewall não depende de CURSOR_SHARING=FORCE para abstrair variações de valores literais.

Protegendo seu Banco de Dados com o SQL Firewall do Oracle 23ai/26ai

Oracle Data Safe e SQL Firewall: conectando um DB System para proteção contra SQL não autorizado

Oracle SQL Firewall no Active Data Guard

Comentários