{"id":1466,"date":"2025-04-02T19:41:18","date_gmt":"2025-04-02T19:41:18","guid":{"rendered":"https:\/\/adrianotanaka.com.br\/?p=1466"},"modified":"2025-04-02T19:45:27","modified_gmt":"2025-04-02T19:45:27","slug":"oracle-23ai-sql-firewall","status":"publish","type":"post","link":"https:\/\/adrianotanaka.com.br\/index.php\/2025\/04\/02\/oracle-23ai-sql-firewall\/","title":{"rendered":"Oracle 23ai &#8211; SQL Firewall"},"content":{"rendered":"\n<p>O SQL Firewall \u00e9 um recurso que foi introduzido na vers\u00e3o 23ai do Oracle Database (aqui voc\u00ea pode conferir as New features desse release) e como o nome j\u00e1 diz, ele atual como um Firewall para comandos SQL tendo como principal vantagem estar integrado diretamente no banco de dados (diferente de outras &nbsp;abordagens que precisam de um servidor dedicado para isso), nesse post abordo suas principais carateristicas e como realizar uma configura\u00e7\u00e3o b\u00e1sica de bloqueio, para isso estou usando o Oracle Database 23ai Free (23.5.0.24.07) e tenho um usu\u00e1rio chamado Tanaka onde as regras ser\u00e3o aplicadas.<\/p>\n\n\n\n<p>O primeiro passo \u00e9 verificar o status e ativar caso ainda n\u00e3o esteja ativo:<\/p>\n\n\n\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<pre class=\"wp-block-code\"><code>select status from&nbsp;&nbsp; dba_sql_firewall_status;<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>exec dbms_sql_firewall.enable; -- Para ativar<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>exec dbms_sql_firewall.enable; -- Para desativar<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p>Ele pode ser ativado tanto a n\u00edvel de CDB quando de PDB.<\/p>\n\n\n\n<p>Todo o gerenciamento do SQL Firewall \u00e9 feito usando a package <strong>DBMS_SQL_FIREWALL<\/strong> e seu fluxo de uso \u00e9 basicamente: Ativar(<strong>dbms_sql_firewall.enable<\/strong>) -> Monitorar comandos (<strong>dbms_sql_firewall.create_capture<\/strong>) -> Configurar as regras de permiss\u00e3o (<strong>dbms_sql_firewall.enable_allow_list<\/strong>) , al\u00e9m disso possu\u00edmos tabelas e views que nos d\u00e3o suporte ao registro do que acontece e das configura\u00e7\u00f5es ativas.<\/p>\n\n\n\n<p>Com o recurso ativo, podemos iniciar a nossa captura (que \u00e9 baseada em um usu\u00e1rio) com o seguinte comando:<\/p>\n\n\n\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<pre class=\"wp-block-code\"><code>begin\ndbms_sql_firewall.create_capture (\n\u00a0 \u00a0 username \u00a0 \u00a0 \u00a0 => 'TANAKA',\n\u00a0 \u00a0 top_level_only => true,\n\u00a0 \u00a0 start_capture \u00a0=> true);\n\nend;\n\/<\/code><\/pre>\n\n\n\n<p>\u00a0<\/p>\n\n\n\n<p><strong>Importante<\/strong>: definindo <strong>top_level_only <\/strong>para TRUE realiza apenas a captura de comandos SQL, caso queira capturar PL\/SQL voc\u00ea precisa definir como FALSE.<\/p>\n<\/div>\n\n\n\n<p>Agora \u00e9 esperar os comandos de sua aplica\u00e7\u00e3o serem executados no banco para que tenhamos uma massa de dados para a configura\u00e7\u00e3o das permiss\u00f5es, aqui irei simular alguns comandos e acesso de diferentes IPs.<\/p>\n\n\n\n<p>Podemos consultar os comandos que foram executados e sess\u00f5es usando as vis\u00f5es <strong>dba_sql_firewall_capture_logs<\/strong> e <strong>dba_sql_firewall_session_logs<\/strong> respectivamente, entendendo os conteudo dessas duas vis\u00f5es vai nos ajudar a montar as regras do nosso ambiente que podem ser baseadas em:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>IP(<strong>dbms_sql_firewall.ip_address<\/strong>)<\/li>\n\n\n\n<li>Usu\u00e1rio do sistema operacional(<strong>dbms_sql_firewall.os_username<\/strong>)<\/li>\n\n\n\n<li>Programa(<strong>dbms_sql_firewall.os_program<\/strong>)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Criando uma libera\u00e7\u00e3o\/Bloqueio<\/h2>\n\n\n\n<p>O ideal \u00e9 que voc\u00ea execute a captura por diversos dias para n\u00e3o correr o risco de deixar algum comando SQL de fora pois ele s\u00f3 vai permitir a execu\u00e7\u00e3o de SQLs que foram capturados.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>begin\ndbms_sql_firewall.enable_allow_list (\n\u00a0 \u00a0 username => 'TANAKA',\n\u00a0 \u00a0 enforce \u00a0=> dbms_sql_firewall.enforce_all,\n\u00a0 \u00a0 block \u00a0 \u00a0=> true);\n\nend;\n\n\/\u00a0 <\/code><\/pre>\n\n\n\n<p>O enforce controla qual o tipo de libera\u00e7\u00e3o\/bloqueio que ser\u00e1 aplicada, ela pode ser baseado em <strong>context<\/strong>(username, program ou IP) ou SQL, aqui vamos colocar <strong>enforce_all <\/strong>para que cubra tudo.<\/p>\n\n\n\n<p>Agora iremos executar alguns selects para analisar o que capturamos, vamos come\u00e7ar com a <strong>dba_sql_firewall_allowed_ip_addr<\/strong>, para acharmos os ips de origem da conex\u00e3o a dica aqui \u00e9 filtrar pelo usu\u00e1rio (where username=\u2019user\u2019):<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"171\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image.png\" alt=\"\" class=\"wp-image-1470\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-300x82.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Se fizermos um select na <strong>dba_sql_firewall_capture_logs <\/strong>podemos identificar os comandos e mais detalhes como por exemplo a origem do comando e o programa:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"364\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-1.png\" alt=\"\" class=\"wp-image-1474\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-1.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-1-300x175.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Se eu tentar executar um comando fora do que foi capturado irei receber o erro <strong>ORA-47605<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"165\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-2.png\" alt=\"\" class=\"wp-image-1475\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-2.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-2-300x79.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Agora se executo um comando que foi capturado a execu\u00e7\u00e3o ocorre sem problemas:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"386\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-3.png\" alt=\"\" class=\"wp-image-1476\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-3.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-3-300x186.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Bloqueando ou adicionando comandos SQL<\/h2>\n\n\n\n<p>Imagine que depois de implementado o allow list, voc\u00ea precise editar o seu conteudo, para realizar o bloqueio voc\u00ea pode:<\/p>\n\n\n\n<p>Executar um select na <strong>DBA_SQL_FIREWALL_ALLOWED_SQL <\/strong>e identificar o <strong>ALLOWED_SQL_ID <\/strong>que deseja bloquear, nela voc\u00ea pode tentar filtrar pelo username e o campo SQL_TEXT:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"108\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-4.png\" alt=\"\" class=\"wp-image-1478\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-4.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-4-300x52.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>E com o <strong>ALLOWED_SQL_ID <\/strong>voc\u00ea pode realizar o bloqueio:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"360\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-5.png\" alt=\"\" class=\"wp-image-1479\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-5.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-5-300x173.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>E caso eu tente o mesmo comando que estava funcionando:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"157\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-6.png\" alt=\"\" class=\"wp-image-1480\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-6.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-6-300x75.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Para adicionar o comando de volta na lista de permiss\u00e3o voc\u00ea pode consultar a <strong>DBA_SQL_FIREWALL_VIOLATIONS <\/strong>buscando o comando:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"122\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-7.png\" alt=\"\" class=\"wp-image-1481\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-7.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-7-300x59.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>E usando <strong>DBMS_SQL_FIREWALL.APPEND_ALLOW_LIST_SINGLE_SQL<\/strong> passando o <strong>SQL_SIGNATURE <\/strong>e o source como <strong>DBMS_SQL_FIREWALL.VIOLATION_LOG<\/strong> (de onde estamos buscando essa info), voc\u00ea consegue voltar a liberar o comando:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"255\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-8.png\" alt=\"\" class=\"wp-image-1482\" style=\"width:624px;height:auto\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-8.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-8-300x123.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"206\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-9.png\" alt=\"\" class=\"wp-image-1483\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-9.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-9-300x99.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Para fazer o controle por IP a ideia \u00e9 a mesma mas nesse caso vamos usar o ADD\/DELETE_ALLOWED_CONTEXT<\/p>\n\n\n\n<p>Para bloquear um IP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BEGIN\nDBMS_SQL_FIREWALL.<strong>DELETE<\/strong>_ALLOWED_CONTEXT (\n\u00a0 \u00a0 username \u00a0 \u00a0 \u00a0 => 'TANAKA',\n\u00a0 \u00a0 context_type \u00a0 => DBMS_SQL_FIREWALL.IP_ADDRESS,\n\u00a0 \u00a0 value \u00a0 \u00a0 \u00a0 \u00a0 \u00a0=> '192.168.56.1'\n \u00a0);\nEND;\n\/<\/code><\/pre>\n\n\n\n<p>\u00a0 <\/p>\n\n\n\n<p>Caso eu tente conectar no banco:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"563\" height=\"237\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-10.png\" alt=\"\" class=\"wp-image-1484\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-10.png 563w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-10-300x126.png 300w\" sizes=\"auto, (max-width: 563px) 100vw, 563px\" \/><\/figure>\n\n\n\n<p>Voc\u00ea pode consultar os ips permitidos na vis\u00e3o DBA_SQL_FIREWALL_ALLOWED_IP_ADDR e caso precise identificar acessos bloqueados voc\u00ea pode ir na DBA_SQL_FIREWALL_VIOLATIONS usando o COMMAND_TYPE=\u2019CONNECT\u2019:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"93\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-11.png\" alt=\"\" class=\"wp-image-1485\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-11.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-11-300x45.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>E para voltar a permitir o acesso desse IP:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"286\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-12.png\" alt=\"\" class=\"wp-image-1486\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-12.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-12-300x138.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>E posso confirmar na <strong>DBA_SQL_FIREWALL_ALLOWED_IP_ADDR <\/strong>que ele est\u00e1 liberado:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"197\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-13.png\" alt=\"\" class=\"wp-image-1487\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-13.png 624w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2025\/04\/image-13-300x95.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Acredito que com essas instru\u00e7\u00f5es voc\u00ea j\u00e1 seja capaz de implementar os recursos b\u00e1sicos do SQL Firewall na vers\u00e3o 23ai do Oracle Database, caso tenha alguma d\u00favida ou tenha encontrado algum problema, sinta-se a vontade para deixar um coment\u00e1rio.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>O SQL Firewall \u00e9 um recurso que foi introduzido na vers\u00e3o 23ai do Oracle Database (aqui voc\u00ea pode conferir as New features desse release) e como o nome j\u00e1 diz, ele atual como um Firewall para comandos SQL tendo como principal vantagem estar integrado diretamente no banco de dados (diferente de outras &nbsp;abordagens que precisam [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1498,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"material-hide-sections":[],"footnotes":""},"categories":[45,6,44,14],"tags":[],"class_list":["post-1466","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-database","category-oracle","category-sec","category-seguranca"],"_links":{"self":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts\/1466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/comments?post=1466"}],"version-history":[{"count":17,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts\/1466\/revisions"}],"predecessor-version":[{"id":1497,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts\/1466\/revisions\/1497"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/media\/1498"}],"wp:attachment":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/media?parent=1466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/categories?post=1466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/tags?post=1466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}