{"id":11897,"date":"2022-10-30T12:56:32","date_gmt":"2022-10-30T11:56:32","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=11897"},"modified":"2023-11-08T18:04:24","modified_gmt":"2023-11-08T17:04:24","slug":"optimizer_secure_view_merging-and-plsql_declarations","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/","title":{"rendered":"optimizer_secure_view_merging and plsql_declarations"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">The Original Problem<\/h2>\n\n\n\n<p>A customer is currently upgrading some Oracle databases from 11.2 to 19c. One query was extremely slow on the new test system and my job was to find out why. The root cause was that the database parameter <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/refrn\/OPTIMIZER_SECURE_VIEW_MERGING.html\">optimizer_secure_view_merging<\/a> was set to a different value. In 19c <code>true<\/code> and <code>false<\/code> in 11.2. This led to a different and in fact bad execution plan in 19c.<\/p>\n\n\n\n<p>Now the question was, should the customer keep the default value of <code>optimizer_secure_view_merging<\/code> in 19c and rewrite the slow query or change the parameter to <code>false<\/code> as in 11.2 to get a good performance without a code change?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What About the <code>opt_param<\/code> Hint?<\/h2>\n\n\n\n<p>Actually, the first thing I tried was the <code>opt_param('optimizer_secure_view_merging','false')<\/code> hint. Unfortunately, this does not work in 19c. It&#8217;s a known bug 28504113. Fixed in 23c. However, I can&#8217;t really recommend waiting for 23c, right?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What About the <code>merge view<\/code> Privilege?<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/GRANT.html#GUID-20B4E2C0-A7F8-4BC8-A5E8-BE61BDC41AC3__BGBHCCFH\">merge any view<\/a> privilege is a good option for highly privileged users and roles. But it should not be granted lightly to any ordinary role or user.<\/p>\n\n\n\n<p>The <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/GRANT.html#d404029e6564\">merge view<\/a> privilege can be granted per view to a user or role. This has a similar scope as a hint in the subquery of a view without having to change the code. In fact, it is an excellent option to override the <code>optimizer_secure_view_merging<\/code> setting for a view. We could <code>grant merge view on &lt;owner&gt;.&lt;view_name&gt; to public<\/code> to mimic the scope of a&nbsp;hint in the subquery of a view.<\/p>\n\n\n\n<p>However, the customer uses a metadata-driven approach to generate the grants for end-user roles as part of the application. And it would require a change of the application to handle this exceptional case. Of course, this grant can easily be hard coded for the view in question, but this is something the customer would like to avoid.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Christian Antognini&#8217;s Recommendation<\/h2>\n\n\n\n<p>Chris explains <code>optimizer_secure_view_merging<\/code> on pages 289 to 291 in <a href=\"https:\/\/antognini.ch\/top\/\">Troubleshooting Oracle Performance, 2nd Edition<\/a>. On page 291 he writes the following:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If you\u2019re neither using views nor VPD for security purposes, I advise you to set the <code>optimizer_secure_view_merging<\/code> initialization parameter to <code>FALSE<\/code>.<\/p>\n<\/blockquote>\n\n\n\n<p>In my case, the customer uses views and protects them with Virtual Private Database policies. According to Chris, the customer should keep the default value <code>true<\/code> for <code>optimizer_secure_view_merging<\/code>. A sound advice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Security Risk Are We Talking About?<\/h2>\n\n\n\n<p><a href=\"https:\/\/antognini.ch\/top\/\">Troubleshooting Oracle Performance, 2nd Edition<\/a> comes with an <a href=\"https:\/\/antognini.ch\/downloads\/top2\/allfiles.zip\">allfiles.zip<\/a> file. It contains a script <code>optimizer_secure_view_merging.sql<\/code> in the folder <code>chapter09<\/code>. Chris used this script to explain the impact of <code>optimizer_secure_view_merging<\/code> in his book. I reused this script here with minor changes.<\/p>\n\n\n\n<p>Let&#8217;s connect as user <code>sys<\/code> and create a database user <code>u1<\/code> for the application data and code and a user <code>u2<\/code> as connect user (with passwords which work in Autonomous Databases). We also disable <code>optimizer_secure_view_merging<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">1) Setup as sys<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create user u1 identified by &quot;AppOwner2022&quot;    default tablespace users quota unlimited on users;\ncreate user u2 identified by &quot;ConnectUser2022&quot; default tablespace users quota unlimited on users;\n\ngrant create session, create table, create procedure, create view, create public synonym to u1;\ngrant create session, create procedure to u2;\n\nalter system set optimizer_secure_view_merging=false scope=memory;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">user<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">u1<\/span><span style=\"color: #D4D4D4\"> identified <\/span><span style=\"color: #569CD6\">by<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;AppOwner2022&quot;<\/span><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">default<\/span><span style=\"color: #D4D4D4\"> tablespace users quota <\/span><span style=\"color: #569CD6\">unlimited<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> users;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">user<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">u2<\/span><span style=\"color: #D4D4D4\"> identified <\/span><span style=\"color: #569CD6\">by<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;ConnectUser2022&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">default<\/span><span style=\"color: #D4D4D4\"> tablespace users quota <\/span><span style=\"color: #569CD6\">unlimited<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> users;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">grant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">session<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">procedure<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> view, <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> public <\/span><span style=\"color: #569CD6\">synonym<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> u1;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">grant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">session<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">procedure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> u2;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">alter<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">system<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> optimizer_secure_view_merging=false scope=memory;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Now we connect as user <code>u1<\/code> and create a table <code>t<\/code> with 6 rows. and a function <code>f<\/code> to filter rows in the view <code>v<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">2) Setup as u1<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create table t (\n  id    number(10) primary key,\n  class number(10),\n  pad   varchar2(10)\n);\n\nexecute dbms_random.seed(0)\n\ninsert into t (id, class, pad)\nselect rownum, mod(rownum, 3), dbms_random.string('a', 10)\n  from dual\nconnect by level <= 6;\n\nexecute dbms_stats.gather_table_stats(user, 't')\n\ncreate or replace function f(in_class in number) return number as\nbegin\n   if in_class = 1 then\n      return 1;\n   else\n      return 0;\n   end if;\nend;\n\/\n\ncreate or replace view v as\n   select *\n     from t\n    where f(class) = 1;\n\ngrant select on v to u2;\n\ncreate or replace public synonym v for u1.v;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">t<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  id    <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">primary key<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  class <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  pad   <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">execute<\/span><span style=\"color: #D4D4D4\"> dbms_random.seed(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">insert into<\/span><span style=\"color: #D4D4D4\"> t (id, class, pad)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> rownum, mod(rownum, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">), dbms_random.string(<\/span><span style=\"color: #CE9178\">&#39;a&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> dual<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">connect<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">by<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">level<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">execute<\/span><span style=\"color: #D4D4D4\"> dbms_stats.gather_table_stats(user, <\/span><span style=\"color: #CE9178\">&#39;t&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create or replace<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">f<\/span><span style=\"color: #D4D4D4\">(in_class <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">as<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">if<\/span><span style=\"color: #D4D4D4\"> in_class = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">if<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create or replace<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">v<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">as<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> t<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">where<\/span><span style=\"color: #D4D4D4\"> f(class) = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">grant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> v <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> u2;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">or<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">replace<\/span><span style=\"color: #D4D4D4\"> public <\/span><span style=\"color: #569CD6\">synonym<\/span><span style=\"color: #D4D4D4\"> v <\/span><span style=\"color: #569CD6\">for<\/span><span style=\"color: #D4D4D4\"> u1.v;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Let&#8217;s connect as user <code>u2<\/code> to query the view.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">3) Query view v as u2<\/span><span role=\"button\" tabindex=\"0\" data-code=\"select id, pad\n  from v\n where id between 1 and 5;\n\n        ID PAD       \n---------- ----------\n         1 DrMLTDXxxq\n         4 AszBGEUGEL\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> id, pad<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> v<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">where<\/span><span style=\"color: #D4D4D4\"> id <\/span><span style=\"color: #569CD6\">between<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        ID PAD       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">---------- ----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> DrMLTDXxxq<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> AszBGEUGEL<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Only two of five rows are returned due to the where clause in the view. So far so good.<\/p>\n\n\n\n<p>The user <code>u2<\/code> has the right to create own functions. And that is a security risk. Why? Because the user can write a <code>spy<\/code>&nbsp;function like in the next example:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">4) Accessing protected data as u2<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create or replace function spy(\n   in_id  in number,\n   in_pad in varchar2\n) return number as\nbegin\n   dbms_output.put_line('id='\n      || in_id\n      || ' pad='\n      || in_pad);\n   return 1;\nend;\n\/\n\nset serveroutput on size unlimited\nselect id, pad\n  from v\n where id between 1 and 5\n   and spy(id, pad) = 1;\n\n        ID PAD       \n---------- ----------\n         1 DrMLTDXxxq\n         4 AszBGEUGEL\n\nid=1 pad=DrMLTDXxxq\nid=2 pad=XOZnqYRJwI\nid=3 pad=nlGfGBTxNk\nid=4 pad=AszBGEUGEL\nid=5 pad=qTSRnFjRGb\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create or replace<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">spy<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   in_id  <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   in_pad <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">as<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   dbms_output.put_line(<\/span><span style=\"color: #CE9178\">&#39;id=&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || in_id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || <\/span><span style=\"color: #CE9178\">&#39; pad=&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      || in_pad);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> serveroutput <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">size<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">unlimited<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> id, pad<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> v<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">where<\/span><span style=\"color: #D4D4D4\"> id <\/span><span style=\"color: #569CD6\">between<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">5<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> spy(id, pad) = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        ID PAD       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">---------- ----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> DrMLTDXxxq<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> AszBGEUGEL<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> pad=DrMLTDXxxq<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> pad=XOZnqYRJwI<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\"> pad=nlGfGBTxNk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> pad=AszBGEUGEL<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\"> pad=qTSRnFjRGb<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Look at the server output for id 3, 4 and 5. By using the spy function in the where clause the user can get access to all rows in table <code>t<\/code>. This is only possible because<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the database parameter <code>optimizer_secure_view_merging<\/code> is set to <code>false<\/code>,<\/li>\n\n\n\n<li>the optimizer applies the <code>spy<\/code> function to an intermediate result and<\/li>\n\n\n\n<li>the user <code>u2<\/code> has the <code>create procedure<\/code> privilege.<\/li>\n<\/ul>\n\n\n\n<p>When you call <code>alter system set optimizer_secure_view_merging=true scope=memory;<\/code> then the result of the previous query looks like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">5) Result with optimizer_secure_view_merging=true<\/span><span role=\"button\" tabindex=\"0\" data-code=\"        ID PAD       \n---------- ----------\n         1 DrMLTDXxxq\n         4 AszBGEUGEL\n\nid=1 pad=DrMLTDXxxq\nid=4 pad=AszBGEUGEL\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">        ID PAD       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">---------- ----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> DrMLTDXxxq<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> AszBGEUGEL<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> pad=DrMLTDXxxq<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> pad=AszBGEUGEL<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The <code>spy<\/code> function does not reveal protected data anymore. Thanks to <code>optimizer_secure_view_merging=true<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Next Problem<\/h2>\n\n\n\n<p>The customer&#8217;s connect users do not have <code>create procedure<\/code> privileges. After all, It&#8217;s a <a href=\"https:\/\/www.salvis.com\/blog\/2018\/07\/18\/the-pink-database-paradigm-pinkdb\/\">PinkDB<\/a> application. Hence I could recommend to set <code>optimizer_secure_view_merging=false<\/code>, because the connect users would not be able to write their own <code>spy<\/code> functions, right?<\/p>\n\n\n\n<p>Wrong. For two reasons.<\/p>\n\n\n\n<p>Firstly, the user could have access to an existing function that might be misused, e.g. a logger function.<\/p>\n\n\n\n<p>Secondly, we are on 19c. And since 12.1 we have <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/SELECT.html#GUID-CFA006CA-6FF1-4972-821E-6996142A51C6__GUID-28DA0E1D-87BF-462E-BCB8-8F77921022F9\">plsql_declarations<\/a> to write PL\/SQL functions and procedures in the&nbsp;<a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/SELECT.html#GUID-CFA006CA-6FF1-4972-821E-6996142A51C6__GUID-7BFCEBF8-6459-4328-8CFC-6FF044E8A147\">with_clause<\/a> of a <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/SELECT.html#GUID-CFA006CA-6FF1-4972-821E-6996142A51C6\">select statement<\/a>. As a result, I can write a <code>spy<\/code> function without the <code>create procedure<\/code> privilege. For example like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">6) Spy function in the with_clause<\/span><span role=\"button\" tabindex=\"0\" data-code=\"set serveroutput on size unlimited\nwith\n   function spy(\n      in_id  in number,\n      in_pad in varchar2\n   ) return number as\n   begin\n      dbms_output.put_line('id='\n         || in_id\n         || ' pad='\n         || in_pad);\n      return 1;\n   end;\nselect id, pad\n  from v\n where id between 1 and 5\n   and spy(id, pad) = 1;\n\/\n\n        ID PAD       \n---------- ----------\n         1 DrMLTDXxxq\n         4 AszBGEUGEL\n\nid=1 pad=DrMLTDXxxq\nid=2 pad=XOZnqYRJwI\nid=3 pad=nlGfGBTxNk\nid=4 pad=AszBGEUGEL\nid=5 pad=qTSRnFjRGb\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">set<\/span><span style=\"color: #D4D4D4\"> serveroutput <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">size<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">unlimited<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">with<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> spy(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_id  <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_pad <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">number<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">as<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      dbms_output.put_line(<\/span><span style=\"color: #CE9178\">&#39;id=&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || in_id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || <\/span><span style=\"color: #CE9178\">&#39; pad=&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || in_pad);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> id, pad<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> v<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">where<\/span><span style=\"color: #D4D4D4\"> id <\/span><span style=\"color: #569CD6\">between<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">5<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> spy(id, pad) = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        ID PAD       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">---------- ----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> DrMLTDXxxq<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> AszBGEUGEL<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> pad=DrMLTDXxxq<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> pad=XOZnqYRJwI<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\"> pad=nlGfGBTxNk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> pad=AszBGEUGEL<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">id=<\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\"> pad=qTSRnFjRGb<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Again, look at the server output for id 3, 4 and 5. Protected data is revealed, even if the user has only the <code>create session<\/code> privilege and <code>optimizer_secure_view_merging<\/code> is set to <code>true<\/code>. IMO this is clearly a security bug.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Database Versions Are Affected?<\/h2>\n\n\n\n<p>I assume that all Oracle Database versions from 12.1 onwards are affected. Including Autonomous Databases. I have explicitly tested the following versions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>OCI as of 2022-10-30:\n<ul class=\"wp-block-list\">\n<li>Autonomous Database 21c (ATP)<\/li>\n\n\n\n<li>Autonomous Database 19c (ADW, AJD)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>On-Premises\n<ul class=\"wp-block-list\">\n<li>Oracle Database XE 21c<\/li>\n\n\n\n<li>Oracle Database Enterprise Edition 19c (19.16)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What Can We Do?<\/h2>\n\n\n\n<p>I created SR 3-31087264311 for this issue. I expect that either a workaround is provided or a bug is opened and a fix will be available soon. I&#8217;ll update this blog post accordingly. <em>(Update on 2023-02-27: Bug 34777606 is referenced in the SR, but not visible. However, it&#8217;s an accepted security bug and fixed in 23c. I&#8217;ve tested it successfully in 23.2. It&#8217;s not planned to include a fix as part of an RU for 19c. However, you can request a one-off patch via SR.).<\/em><\/p>\n\n\n\n<p>In any case, if you have views or VPD policies for security purposes, set <code>optimizer_secure_view_merging=true<\/code> and ensure that the connect users do not have the <code>create procedure<\/code> privilege. Follow the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Principle_of_least_privilege\">principle of least privileges<\/a>.<\/p>\n\n\n\n<p>As a workaround, you can use <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/dbseg\/configuring-audit-policies.html#GUID-B706FF6F-13A6-4944-AFCB-29971F5076FD\">Fine-Grained Auditing<\/a> to identify statements with <code>plsql_declarations<\/code>. You can either log them or abort the execution as in the following example:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">7) Abort execution of statements with plsql_declarations (as sys)<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create or replace procedure u1.suppress_plsql_delcarations_handler(\n   in_object_owner in varchar2,\n   in_object_name  in varchar2,\n   in_policy_name  in varchar2\n) is\nbegin\n   if regexp_like(sys_context('userenv', 'current_sql'), 'with[^fp]+(function|procedure)', 'i') then\n      raise_application_error(-20942, 'plsql_declarations are not allowed in the with_clause. See policy '\n         || in_policy_name\n         || ' for '\n         || in_object_owner\n         || '.'\n         || in_object_name);\n   end if;\nend;\n\/\n\nbegin\n   dbms_fga.add_policy(\n      object_schema   =&gt; 'U1',\n      object_name     =&gt; 'V',\n      policy_name     =&gt; 'SUPPRESS_PLSQL_DELCARATIONS_POLICY',\n      handler_schema  =&gt; 'U1',\n      handler_module  =&gt; 'SUPPRESS_PLSQL_DELCARATIONS_HANDLER',\n      statement_types =&gt; 'SELECT,INSERT,UPDATE,DELETE'\n   );\nend;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">create or replace<\/span><span style=\"color: #D4D4D4\"> procedure u1.suppress_plsql_delcarations_handler(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   in_object_owner <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   in_object_name  <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   in_policy_name  <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">is<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> regexp_like(<\/span><span style=\"color: #DCDCAA\">sys_context<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;userenv&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;current_sql&#39;<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&#39;with[^fp]+(function|procedure)&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;i&#39;<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #DCDCAA\">raise_application_error<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #B5CEA8\">20942<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;plsql_declarations are not allowed in the with_clause. See policy &#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || in_policy_name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || <\/span><span style=\"color: #CE9178\">&#39; for &#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || in_object_owner<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || <\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         || in_object_name);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">end if<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #DCDCAA\">dbms_fga.<\/span><span style=\"color: #4EC9B0\">add_policy<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      object_schema   =&gt; <\/span><span style=\"color: #CE9178\">&#39;U1&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      object_name     =&gt; <\/span><span style=\"color: #CE9178\">&#39;V&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      policy_name     =&gt; <\/span><span style=\"color: #CE9178\">&#39;SUPPRESS_PLSQL_DELCARATIONS_POLICY&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      handler_schema  =&gt; <\/span><span style=\"color: #CE9178\">&#39;U1&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      handler_module  =&gt; <\/span><span style=\"color: #CE9178\">&#39;SUPPRESS_PLSQL_DELCARATIONS_HANDLER&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      statement_types =&gt; <\/span><span style=\"color: #CE9178\">&#39;SELECT,INSERT,UPDATE,DELETE&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-text-align-left\">You have to register a policy for each view. This can be easily generated. However, you should consider that such a policy has an impact on performance. Therefore, you should define such a policy only when needed.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-text-align-left\"><em>Updated on 2022-11-02, documented workaround via <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/arpls\/DBMS_FGA.html#GUID-DC7B93AE-4390-4D27-9CAC-43DC932D8622\">DBMS_FGA<\/a>.<\/em><\/p>\n\n\n\n<p class=\"has-text-align-left\"><em>Updated on 2022-11-03, updated workaround regarding comments before <code>plsql_declarations<\/code> and support for all DML statements.<\/em><\/p>\n\n\n\n<p class=\"has-text-align-left\"><em>Updated on 2023-03-13, added reference to bug 34777606 (not visible), fixed in 23c, no information regarding backport yet.<\/em><\/p>\n\n\n\n<p class=\"has-text-align-left\"><em>Updated on 2023-03-27,&nbsp; &#8220;Bug 34255928 &#8211; INCORRECT SECURE VIEW MERGING FOR A QUERY WITH A FUNCTION DEFINED IN ITS WITH CLAUSE&#8221; fixed in 23c, backport possible as a one-off patch via SR. No plans to include it in an RU for 19c.<\/em><\/p>\n\n\n\n<p class=\"has-text-align-left\"><em>Updated on 2023-04-05: Tested successfully in 23c, <span class=\"s1\">Developer-Release Version 23.2.0.0.0<\/span><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Original Problem A customer is currently upgrading some Oracle databases from 11.2 to 19c. One query was extremely slow on the new test system and my job was to find out why. The root cause was that the database parameter optimizer_secure_view_merging was set to a different value. In 19c true and<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":11910,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[127,109,13,85],"class_list":["post-11897","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-autonomous-database","tag-pinkdb","tag-plsql","tag-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>optimizer_secure_view_merging and plsql_declarations - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"You may feel safe when optimizer_secure_view_merging is enabled. Still, you can gain access to protected data via plsql_declarations.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"optimizer_secure_view_merging and plsql_declarations - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"You may feel safe when optimizer_secure_view_merging is enabled. Still, you can gain access to protected data via plsql_declarations.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-10-30T11:56:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-08T17:04:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2022\/10\/cyber-security-digital-2820828.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"1200\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"optimizer_secure_view_merging and plsql_declarations\",\"datePublished\":\"2022-10-30T11:56:32+00:00\",\"dateModified\":\"2023-11-08T17:04:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/\"},\"wordCount\":1105,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/cyber-security-digital-2820828.jpg\",\"keywords\":[\"Autonomous Database\",\"PinkDB\",\"PL\\\/SQL\",\"SQL\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/\",\"name\":\"optimizer_secure_view_merging and plsql_declarations - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/cyber-security-digital-2820828.jpg\",\"datePublished\":\"2022-10-30T11:56:32+00:00\",\"dateModified\":\"2023-11-08T17:04:24+00:00\",\"description\":\"You may feel safe when optimizer_secure_view_merging is enabled. Still, you can gain access to protected data via plsql_declarations.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/cyber-security-digital-2820828.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/cyber-security-digital-2820828.jpg\",\"width\":1200,\"height\":1200,\"caption\":\"optimizer_secure_view_merging=true\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2022\\\/10\\\/30\\\/optimizer_secure_view_merging-and-plsql_declarations\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"optimizer_secure_view_merging and plsql_declarations\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"optimizer_secure_view_merging and plsql_declarations - Philipp Salvisberg&#039;s Blog","description":"You may feel safe when optimizer_secure_view_merging is enabled. Still, you can gain access to protected data via plsql_declarations.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/","og_locale":"en_US","og_type":"article","og_title":"optimizer_secure_view_merging and plsql_declarations - Philipp Salvisberg&#039;s Blog","og_description":"You may feel safe when optimizer_secure_view_merging is enabled. Still, you can gain access to protected data via plsql_declarations.","og_url":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2022-10-30T11:56:32+00:00","article_modified_time":"2023-11-08T17:04:24+00:00","og_image":[{"width":1200,"height":1200,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2022\/10\/cyber-security-digital-2820828.jpg","type":"image\/jpeg"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"optimizer_secure_view_merging and plsql_declarations","datePublished":"2022-10-30T11:56:32+00:00","dateModified":"2023-11-08T17:04:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/"},"wordCount":1105,"commentCount":3,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2022\/10\/cyber-security-digital-2820828.jpg","keywords":["Autonomous Database","PinkDB","PL\/SQL","SQL"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/","url":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/","name":"optimizer_secure_view_merging and plsql_declarations - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2022\/10\/cyber-security-digital-2820828.jpg","datePublished":"2022-10-30T11:56:32+00:00","dateModified":"2023-11-08T17:04:24+00:00","description":"You may feel safe when optimizer_secure_view_merging is enabled. Still, you can gain access to protected data via plsql_declarations.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2022\/10\/cyber-security-digital-2820828.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2022\/10\/cyber-security-digital-2820828.jpg","width":1200,"height":1200,"caption":"optimizer_secure_view_merging=true"},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2022\/10\/30\/optimizer_secure_view_merging-and-plsql_declarations\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"optimizer_secure_view_merging and plsql_declarations"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/11897","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=11897"}],"version-history":[{"count":56,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/11897\/revisions"}],"predecessor-version":[{"id":12728,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/11897\/revisions\/12728"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/11910"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=11897"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=11897"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=11897"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}