ORA-47605 após uma atualização da aplicação? Como atualizar a allow-list do Oracle SQL Firewall

Após implementar o SQL Firewall a governança é indispensável. O firewall atua bloqueando instruções SQL não autorizadas e tentativas de injeção, mas as regras precisam de manutenção constante para acompanhar a evolução/atualização dos sistemas.

Por isso, nem todo ORA-47605: SQL Firewall violation indica necessariamente que está ocorrendo um ataque. Este erro também pode indicar que um novo SQL ainda não faz parte da allow-list.

A Oracle define o ORA-47605 como uma operação bloqueada pelo SQL Firewall em função da política atualmente aplicada. A recomendação é revisar a política e modificá-la quando o bloqueio não for intencional.

Neste artigo veremos como adicionar um novo SQL bloqueado à allow-list, sem precisar recriar toda a política.

Cenário:

  • Host: oracle26ai
  • Usuário operacional: oracle
  • Cliente: SQL*Plus
  • SQL*Plus: 23.26.1.0.0
  • Banco: Oracle AI Database 26ai
  • Edição: Enterprise Edition
  • Release: 23.26.1.0.0
  • Arquitetura: Multitenant
  • PDB utilizada: ORA26AI_PDB1

Listando as allow-lists existentes

Através da view DBA_SQL_FIREWALL_ALLOW_LISTS, podemos validar quais usuários possuem allow-list configurada. Mostrando o usuário, status, modo de enforcement e de bloqueio. 
No exemplo abaixo, vemos que existe uma configuração para o usuário FW_DEMO_APP.

QL> SELECT username,
        status,
        status_updated_on,
        top_level_only,
        enforce,
        block
FROM dba_sql_firewall_allow_lists
ORDER BY username;  2    3    4    5    6    7    8

USERNAME             STATUS   STATUS_UPDATED_ON                                                           TOP_LEVEL_ONLY ENFORCE         BLOCK
-------------------- -------- --------------------------------------------------------------------------- -------------- --------------- --------------
FW_DEMO_APP          ENABLED  15-AUG-26 01.27.41.336582 PM +00:00                                         N              ENFORCE_ALL     Y

SQL>

Os possíveis modos de enforcement documentados para a allow-list são ENFORCE_CONTEXT, ENFORCE_SQL e ENFORCE_ALL. Com BLOCK=Y, uma violação sujeita à política pode ser bloqueada.

Cenário pós atualização

Considere agora que uma nova versão da aplicação foi disponibilizada. Antes da atualização, determinada funcionalidade executava apenas SQLs já conhecidos pelo Firewall.

Depois da alteração, a aplicação passou a executar um novo comando. Esse SQL ainda não existe na allow-list.

Se a política estiver habilitada para enforcement de SQL e em blocking mode, a aplicação pode receber: ORA-47605: SQL Firewall violation

Na simulação a aplicação recebeu o erro:
SQL>
SQL> select 1 from dual;
select 1 from dual
              *
ERROR at line 1:
ORA-47605: SQL Firewall violation
Help: https://docs.oracle.com/error-help/db/ora-47605/


SQL>

Localizando a violação

Através da view dba_sql_firewall_violations é possível localizar as violações recentes para que sejam identificadas e tratadas.

Exemplo do comando:
SELECT
    occurred_at,
    username,
    command_type,
    sql_signature,
    current_user,
    top_level,
    cause,
    firewall_action,
    ip_address,
    client_program,
    os_user,
    sql_text
FROM
    dba_sql_firewall_violations
WHERE
    username = 'FW_DEMO_APP'
ORDER BY
    occurred_at DESC;

A coluna CAUSE merece atenção pois vai apresentar o motivo da violação (SQL violation ou Context violation). Caso aparece Context violation o ponto de atenção deve ser maior uma vez que indica que o endereço IP, usuário de sistema operacional ou programa cliente estão sendo violados.

Caso o teste tenha acabado de ser executado e ainda não conste o registro é possível forçar o flush dos logs através do comando:
SQL>
SQL> EXEC DBMS_SQL_FIREWALL.FLUSH_LOGS;

PL/SQL procedure successfully completed.

SQL>

Antes de liberar o SQL confirme que o mesmo realmente faz parte da atualização. A existência do ORA-47605 imediatamente depois de uma atualização não prova por si só que o SQL bloqueado faz parte daquela release.

Antes de aprovar a mudança, valide pelo menos:
  • se o SQL faz parte da funcionalidade alterada;
  • se os objetos acessados são coerentes;
  • se o horário coincide com o deployment;
  • se o client program corresponde à aplicação;
  • se a origem da conexão é esperada;
  • se o SQL foi revisado pelo responsável pela aplicação;
  • se não há indícios de SQL Injection ou utilização indevida da conta.
Somente depois dessa análise o SQL deve ser tratado como legítimo.

Realizando a liberação do SQL

documentação oficial orienta o identificar o USERNAME, SQL_SIGNATURE, CURRENT_USER e TOP_LEVEL no registro correspondente do capture log ou violation log para realizar a liberação.
SELECT
    username,
    sql_signature,
    current_user,
    top_level,
    sql_text
FROM
    dba_sql_firewall_violations
WHERE
    username = 'FW_DEMO_APP'
ORDER BY
    occurred_at DESC;

Exemplo apenas para demonstrar a estrutura:

USERNAME       : FW_DEMO_APP
SQL_SIGNATURE: 84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195
CURRENT_USER   : FW_DEMO_APP
TOP_LEVEL      : Y

Será usado o DBMS_SQL_FIREWALL.APPEND_ALLOW_LIST_SINGLE_SQL para atualizar a allow-list com o SQL desejado.

SQL>
SQL>
SQL> BEGIN
  2      dbms_sql_firewall.append_allow_list_single_sql(
        username      => 'FW_DEMO_APP',
        sql_signature => '84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195',
  3    4    5          current_user  => 'FW_DEMO_APP',
        top_level     => 'Y',
        source        => dbms_sql_firewall.violation_log
    );
END;
/  6    7    8    9   10

PL/SQL procedure successfully completed.

SQL>

No comando acima:
  • username -  é o usuário protegido pela allow-list.
  • sql_signature - é a assinatura exata localizada no violation log.
  • current_user -  é o valor apresentado na violation e não deve ser presumido como sendo sempre igual ao USERNAME.
  • top_level - deve corresponder exatamente a Y ou N apresentado no registro.
  • source - indica onde o SQL será localizado. 
Podemos confirmar a inclusão atraves a consulta:
SQL> col CURRENT_USER for a15
SQL> col SQL_TEXT for a30
SQL> SELECT
  2      username,
  3      allowed_sql_id,
    sql_signature,
  4    5      current_user,
    top_level,
  6    7      version,
    sql_text
FROM
    dba_sql_firewall_allowed_sql
WHERE
        username = 'FW_DEMO_APP'
  8    9   10   11   12   13      AND sql_signature = '84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195';

USERNAME             ALLOWED_SQL_ID SQL_SIGNATURE                                                    CURRENT_USER    TOP_LEVEL    VERSION SQL_TEXT
-------------------- -------------- ---------------------------------------------------------------- --------------- --------- ---------- ------------------------------
FW_DEMO_APP                      32 84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195 FW_DEMO_APP     Y                  2 SELECT :"SYS_B_0" FROM DUAL

SQL>
SQL>

Validando agora via aplicação (na mesma sessão sem logar novamente).
SQL>
SQL> select 1 from dual;
select 1 from dual
              *
ERROR at line 1:
ORA-47605: SQL Firewall violation
Help: https://docs.oracle.com/error-help/db/ora-47605/


SQL> select 1 from dual;

         1
----------
         1

SQL>

Rollback

Suponha que, depois da inclusão, a equipe de segurança determine que aquele SQL não deveria ter sido autorizado.

Primeiro obtenha o ALLOWED_SQL_ID:
SQL>
SQL> SELECT
  2      allowed_sql_id,
    sql_signature,
    current_user,
    top_level,
    version,
    sql_text
FROM
    dba_sql_firewall_allowed_sql
  3    4    5    6    7    8    9   10  WHERE
        username = 'FW_DEMO_APP'
 11   12      AND sql_signature = '84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195';

ALLOWED_SQL_ID SQL_SIGNATURE                                                    CURRENT_USER    TOP_LEVEL    VERSION SQL_TEXT
-------------- ---------------------------------------------------------------- --------------- --------- ---------- ------------------------------
            32 84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195 FW_DEMO_APP     Y                  2 SELECT :"SYS_B_0" FROM DUAL

Depois remova somente a entrada correspondente:
SQL>
SQL> BEGIN
    DBMS_SQL_FIREWALL.DELETE_ALLOWED_SQL(
        username       => 'FW_DEMO_APP',
        allowed_sql_id => 32
    );
END;
/
  2    3    4    5    6    7
PL/SQL procedure successfully completed.

SQL>

O DELETE_ALLOWED_SQL utiliza o usuário e o identificador ALLOWED_SQL_ID. Ele pode ser executado com a allow-list habilitada ou desabilitada, e sua alteração também entra em vigor imediatamente.

Valide:
SQL>
SQL> SELECT allowed_sql_id,
       sql_signature,
       sql_text
FROM dba_sql_firewall_allowed_sql
WHERE username = 'FW_DEMO_APP'
  AND sql_signature = '84106AD16408952BDF6F0056C3D475F672544792B87786B2038920C147CBB195';  2    3    4    5    6

no rows selected

SQL>

Conclusão 

O ORA-47605 após um deployment não deve ser tratado apenas como um obstáculo operacional.

Em um ambiente protegido pelo Oracle SQL Firewall, ele pode representar exatamente o comportamento esperado do mecanismo: uma aplicação começou a executar algo que ainda não fazia parte do comportamento previamente autorizado.

Veja Também:

Comentários