{"id":160,"date":"2026-04-11T12:00:00","date_gmt":"2026-04-11T10:00:00","guid":{"rendered":"https:\/\/blog.agdba.de\/?p=160"},"modified":"2026-04-13T07:40:21","modified_gmt":"2026-04-13T05:40:21","slug":"oracle-sql-firewall-pl-sql-package","status":"publish","type":"post","link":"https:\/\/blog.agdba.de\/?p=160","title":{"rendered":"SQL-Firewall mittels PL\/SQL-Package und Datasafe"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ab der Version 23ai ist die SQL Firewall Teil des Oracle Kernels. Die Firewall kann \u00fcber das PL\/SQL-Package DBMS_SQL_FIREWALL administriert werden. Dieser Artikel soll die Einrichtung und die Funktionsweise aufzeigen.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Einrichtung<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Aktivieren der SQL Firewall in der PDB (als sys oder priviligierter User):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; exec dbms_sql_firewall.enable;\n\nPL\/SQL procedure successfully completed.\n\nSQL&gt; set lines 300\nSQL&gt; select * from dba_sql_firewall_status;\n\nSTATUS\t STATUS_UPDATED_ON\t\t\t\t\t\t\t     EXCLUDE_JOBS\n-------- --------------------------------------------------------------------------- ------------\nENABLED  10-APR-26 11.30.39.795661 AM +00:00\t\t\t\t\t     Y\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Starten des Captures Prozesses zum erfassen des Workloads:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; BEGIN\n    DBMS_SQL_FIREWALL.CREATE_CAPTURE (\n      username =&gt; 'APP',\n      top_level_only =&gt; TRUE,\n      start_capture =&gt; FALSE );\nEND;\n\/\n  2    3    4    5    6    7  \nPL\/SQL procedure successfully completed.\n\n\nSQL&gt; select username, top_level_only, status from dba_sql_firewall_captures where username='APP';\n\nUSERNAME     TOP_LEVEL_ONLY STATUS\n------------ -------------- --------\nAPP\t     Y\t\t    DISABLED\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das Capture muss jetzt noch gestartet werden, da start_capture auf False gesetzt wurde:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; exec dbms_sql_firewall.start_capture ('APP');\n\nPL\/SQL procedure successfully completed.\n\nSQL&gt; select username, top_level_only, status from dba_sql_firewall_captures where username='APP';\nSQL&gt; \nUSERNAME     TOP_LEVEL_ONLY STATUS\n------------ -------------- --------\nAPP\t     N\t\t    ENABLED<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt kann der Workload ausgef\u00fchrt werden, der sp\u00e4ter die Grundlage f\u00fcr die sp\u00e4tere Allow List sein soll.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Daf\u00fcr f\u00fchren wir einige SQL als Benutzer APP in der PDB aus.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Stoppen des Capture Prozesses:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; exec dbms_sql_firewall.stop_capture('APP');\n\nPL\/SQL procedure successfully completed.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In folgenden Views sind die erfassten SQLs und die Session Kontexte einzusehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>--session logs (context)\nSQL&gt; select username, ip_address, client_program, os_user\nfrom dba_sql_firewall_session_logs\nwhere username = 'APP' order by login_time;  2    3  \n\nUSERNAME     IP_ADDRESS      CLIENT_PROGRAM OS_USER\n------------ --------------- -------------- --------------------\nAPP\t     10.0.0.215      sqlplus@dbfire oracle\n\t\t\t     wall (TNS V1-V\n\t\t\t     3)\n\n\n\n--capture logs (SQLs)\nSQL&gt; SQL&gt; select command_type, sql_text, accessed_objects from dba_sql_firewall_capture_logs;\n\nCOMMAND_TYPE\tSQL_TEXT\t\t\t\t\t   ACCESSED_OBJECTS\n--------------- -------------------------------------------------- --------------------\nSELECT\t\tSELECT SUM (PREIS) FROM BESTELLUNGEN WHERE KUNDENN \"APP\".\"BESTELLUNGEN\"\n\t\tR=:\"SYS_B_0\"\n\nEXECUTE \tBEGIN BESTELLSUM (?); END;\t\t\t   \"APP\".\"BESTELLSUM\"\nSELECT\t\tSELECT COUNT (*) FROM BESTELLUNGEN WHERE KUNDENNR= \"APP\".\"BESTELLUNGEN\"\n\t\t:\"SYS_B_0\"\n\nSELECT\t\tSELECT KUNDENNR,ARTIKEL,PREIS,MENGE FROM BESTELLUN \"APP\".\"BESTELLUNGEN\"\n\t\tGEN WHERE KUNDENNR=:\"SYS_B_0\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hier sind die SQL-Muster zu sehen, die erfasst wurden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aus diesen Ergebnissen kann dann die Allowlist generiert werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; exec dbms_sql_firewall.generate_allow_list('APP');\n\nPL\/SQL procedure successfully completed.\n\n-- view allow list\nSQL&gt; select username, status, top_level_only from dba_sql_firewall_allow_lists where username='APP';\n\nUSERNAME     STATUS   TOP_LEVEL_ONLY\n------------ -------- --------------\nAPP\t     DISABLED N\n\n-- view allowed SQLs\nSQL&gt; select username, current_user, top_level, sql_text, accessed_objects from dba_sql_firewall_allowed_sql where username='APP' order by sql_text, current_user, top_level;\n\nUSERNAME     CURRENT_USER TOP_LEVEL SQL_TEXT\t\t\t\t\t       ACCESSED_OBJECTS\n------------ ------------ --------- -------------------------------------------------- --------------------\nAPP\t     APP\t  Y\t    BEGIN BESTELLSUM (?); END;\t\t\t       \"APP\".\"BESTELLSUM\"\nAPP\t     APP\t  Y\t    SELECT COUNT (*) FROM BESTELLUNGEN WHERE KUNDENNR= \"APP\".\"BESTELLUNGEN\"\n\t\t\t\t    :\"SYS_B_0\"\n\nAPP\t     APP\t  Y\t    SELECT KUNDENNR,ARTIKEL,PREIS,MENGE FROM BESTELLUN \"APP\".\"BESTELLUNGEN\"\n\t\t\t\t    GEN WHERE KUNDENNR=:\"SYS_B_0\"\n\nAPP\t     APP\t  N\t    SELECT SUM (PREIS) FROM BESTELLUNGEN WHERE KUNDENN \"APP\".\"BESTELLUNGEN\"\n\t\t\t\t    R=:\"SYS_B_0\"\n\n\n-- view allowed contexts\nSQL&gt; select username, ip_address from sys.dba_sql_firewall_allowed_ip_addr where username='APP';\n\nUSERNAME     IP_ADDRESS\n------------ ---------------\nAPP\t     10.0.0.215\n\nSQL&gt; select username, os_user from sys.dba_sql_firewall_allowed_os_user where username='APP';\n\nUSERNAME     OS_USER\n------------ --------------------\nAPP\t     oracle\n\nSQL&gt; select username, os_program from sys.dba_sql_firewall_allowed_os_prog where username='APP';\n\nUSERNAME     OS_PROGRAM\n------------ --------------------------------------------------------------------------------------------------------------------------------\nAPP\t     sqlplus@dbfirewall (TNS V1-V3)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aktivieren der Allowlist:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; BEGIN\n  DBMS_SQL_FIREWALL.ENABLE_ALLOW_LIST (\n    username       =&gt; 'APP',\n    enforce        =&gt; DBMS_SQL_FIREWALL.ENFORCE_SQL,\n    block          =&gt; TRUE\n  );\nEND;\n\/  2    3    4    5    6    7    8  \n\nPL\/SQL procedure successfully completed.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hierbei k\u00f6nnen verschiedenen Parameter verwendet werden:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">enforce =&gt;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ENFORCE_ALL  &#8211;&gt; default, SQLs und Kontext werden angewendet<\/li>\n\n\n\n<li>ENFORCW_SQL &#8211;&gt; nur SQLs werden angewendet<\/li>\n\n\n\n<li>ENFORCE_CONTEXT &#8211;&gt; nur Session Kontext wird angewendet<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">block =&gt;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>false &#8211;&gt; default, Violations werden nicht geblockt, nur protokolliert (View DBA_SQL_FIREWALL_VIOLATIONS).<\/li>\n\n\n\n<li>true &#8211;&gt; Violations werden geblockt und protokolliert (View DBA_SQL_FIREWALL_VIOLATIONS).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c4ndern des Block-Modus f\u00fcr die Allow-List:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>exec dbms_sql_firewall.update_allow_list_enforcement('APP', block=&gt;FALSE);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Anpassungen der Allowlist k\u00f6nnen jederzeit gemacht werden.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>--hinzuf\u00fcgen eines erlaubten OS Benutzers\nBEGIN\n  DBMS_SQL_FIREWALL.ADD_ALLOWED_CONTEXT (\n    username       =&gt; 'APP',\n    context_type   =&gt; DBMS_SQL_FIREWALL.OS_USERNAME,\n    value          =&gt; 'opc'\n   );\nEND;\n\/\n\n--entfernen eines erlaubten OS Benutzers\nBEGIN\n  DBMS_SQL_FIREWALL.DELETE_ALLOWED_CONTEXT (\n    username       =&gt; 'APP',\n    context_type   =&gt; DBMS_SQL_FIREWALL.OS_USERNAME,\n    value          =&gt; 'opc'\n   );\nEND;\n\/\n\n--entfernen einer erlaubten IP Adresse:\nBEGIN\n  DBMS_SQL_FIREWALL.DELETE_ALLOWED_CONTEXT (\n    username       =&gt; 'APP',\n    context_type   =&gt; DBMS_SQL_FIREWALL.IP_Address,\n    value          =&gt; '192.168.1.70'\n   );\nEND;\n\/\n\n--entfernen eines erlaubten Programms\nBEGIN\n  DBMS_SQL_FIREWALL.DELETE_ALLOWED_CONTEXT (\n    username       =&gt; 'APP',\n    context_type   =&gt; DBMS_SQL_FIREWALL.OS_PROGRAM,\n    value          =&gt; 'sqlplus.exe'\n   );\nEND;\n\/<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Testen der Funktion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Um die Funktion zu testen, werden verschiedene SQL Statements ausgef\u00fchrt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SQL mit identischer where Bedingung:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; select count(*) from bestellungen where kundennr='123456';\n\n  COUNT(*)\n----------\n\t 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SQL mit ge\u00e4nderter where-Bedingung:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nSQL&gt; select count(*) from bestellungen;\nselect count(*) from bestellungen\n                     *\nERROR at line 1:\nORA-47605: SQL Firewall violation\nHelp: https:\/\/docs.oracle.com\/error-help\/db\/ora-47605\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SQL mit ge\u00e4nderter Spaltenwahl (urspr\u00fcnglich: &#8222;select kundennr, artikel, preis, menge from bestellungen where kundennr=&#8217;123456&#8242;;&#8220;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL&gt; select preis, menge from bestellungen where kundennr='123456';\nselect preis, menge from bestellungen where kundennr='123456'\n                         *\nERROR at line 1:\nORA-47605: SQL Firewall violation\nHelp: https:\/\/docs.oracle.com\/error-help\/db\/ora-47605\/\n\nSQL&gt; select preis, menge ,kundennr, artikel from bestellungen where kundennr='123456';\nselect preis, menge ,kundennr, artikel from bestellungen where kundennr='123456'\n                                            *\nERROR at line 1:\nORA-47605: SQL Firewall violation\nHelp: https:\/\/docs.oracle.com\/error-help\/db\/ora-47605\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Mit der SQL Firewall kann somit die Sicherheit von sensiblen Daten erh\u00f6ht werden. Die SQL Firewall sch\u00fctzt haupts\u00e4chlich vor missbrauch von priviligierten Benutzern und SQL-Injections, da unbekannte SQL Muster oder Quellen der Verbindung blockiert werden, bevor die SQLs in der Datenbank ausgef\u00fchrt werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nutzung in der OCI Datasafe<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In der OCI kann im Datasafe die SQL-Firewall grafisch bedient und administriert werden. Dabei k\u00f6nnen Ziele in der OCI und auch onPrem von Datasafe administriert werden. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nachfolgend einige Bilder f\u00fcr die adminsitration der SQL-Firewall mittels Datasafe:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Anzeige der Kontextinformationen und erlaubten SQLs:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"489\" src=\"https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3-1024x489.png\" alt=\"\" class=\"wp-image-252\" srcset=\"https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3-1024x489.png 1024w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3-300x143.png 300w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3-768x367.png 768w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3-700x335.png 700w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3-837x400.png 837w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild3.png 1519w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ebenfalls zu sehen sind hier die Administrationsm\u00f6glichkeiten wie z.B. L\u00f6schen von SQLs aus der Allowed_list oder &#8222;Add from violations&#8220; womit man auf Violations reagieren kann, die ungewollt entstehen. Die Allow_Lists f\u00fcr SQL und Kontext sind somit flexibel modifizierbar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dashboard f\u00fcr SQL-Firewall mit \u00fcbersicht \u00fcber Anzahl der violations, SQL-Firewall rules und SQL Collections:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"291\" src=\"https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild4-1024x291.png\" alt=\"\" class=\"wp-image-254\" srcset=\"https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild4-1024x291.png 1024w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild4-300x85.png 300w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild4-768x218.png 768w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild4-700x199.png 700w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild4.png 1325w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Details der SQL-Violations:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"389\" src=\"https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5-1024x389.png\" alt=\"\" class=\"wp-image-255\" srcset=\"https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5-1024x389.png 1024w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5-300x114.png 300w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5-768x292.png 768w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5-700x266.png 700w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5-1052x400.png 1052w, https:\/\/blog.agdba.de\/wp-content\/uploads\/2025\/12\/Bild5.png 1525w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Im Datasafe in der OCI k\u00f6nnen aus diesen Ansichten auch Reports geneiert werden. Datasafe erm\u00f6glicht zudem auch die Nutzung von Notifications im Falle von Firewall violoations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ab der Version 23ai ist die SQL Firewall Teil des Oracle Kernels. Die Firewall kann \u00fcber das PL\/SQL-Package DBMS_SQL_FIREWALL administriert werden. Dieser Artikel soll die Einrichtung und die Funktionsweise aufzeigen.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,13,15,14],"tags":[23,24,30,29,19,27,28,26,25],"class_list":["post-160","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-database","category-oci","category-security","tag-23ai","tag-26ai","tag-datasafe","tag-dbms_sql_firewall","tag-oci","tag-oracle-database","tag-pl-sql-package","tag-security","tag-sql-firewall"],"_links":{"self":[{"href":"https:\/\/blog.agdba.de\/index.php?rest_route=\/wp\/v2\/posts\/160","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.agdba.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.agdba.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.agdba.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.agdba.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=160"}],"version-history":[{"count":18,"href":"https:\/\/blog.agdba.de\/index.php?rest_route=\/wp\/v2\/posts\/160\/revisions"}],"predecessor-version":[{"id":263,"href":"https:\/\/blog.agdba.de\/index.php?rest_route=\/wp\/v2\/posts\/160\/revisions\/263"}],"wp:attachment":[{"href":"https:\/\/blog.agdba.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.agdba.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.agdba.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}