1

I'm using an Oracle 19 DB that is structured into multiple layers by using DB users. Here is a simplified overview of the structure:

  • User DATA: Has the table XTEST and the view TEST. The view is created with a CREATE VIEW TEST AS SELECT * FROM XTEST statement, so it contains all columns of the table.
  • User APP: Uses the view DATA.TEST for all SQL and DML.
    The APP user does not have any grants on the table DATA.XTEST, but does have SELECT,INSERT,UPDATE,DELETE grants on the view DATA.TEST.

Now to my problem:
If a NOT NULL constraint on the table DATA.XTEST is violated, the error message doesn't show the column name. The error message is literally:

ORA-01400: cannot insert NULL into (???)

The DB used Oracle 11 some time ago and back then we had the same problem, but could fix it by granting the REFERENCES privilege on the table DATA.XTEST to the APP user (see related question: Grant privilege to see column names in null constraint violations when inserting in views). But this doesn't work any more in Oracle 19.

Does anyone know how to get the column name in the error message?

  • grant select on data.xtest to app; – Balazs Papp Jun 23 at 8:11
  • @BalazsPapp The APP user must not have SELECT privileges on the actual table. The view might filter out some data that the app is not allowed to see. – cremor Jun 23 at 8:51
1

Other than the obvious solution (grant select on data.xtest to app;), you can revert to the old behavior by setting SQL92_SECURITY to FALSE. In 11.2, its default value was FALSE, but in 19c, its default value is TRUE.

alter system set sql92_security=false scope=spfile;

Then restart the database, as this parameter can not be changed online.

Demo:

create table bp.test (c1 number not null);
create view bp.xtest as select * from bp.test;
create user u1 identified by u1;
grant create session to u1;
grant select, insert, update, delete on bp.xtest to u1;
grant references on bp.test to u1;

SQL> show parameter sql92

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sql92_security                       boolean     TRUE
SQL>

SQL> conn u1/u1
Connected.

SQL> insert into bp.xtest values(null);
insert into bp.xtest values(null)
*
ERROR at line 1:
ORA-01400: cannot insert NULL into (???)

By changing the parameter:

SQL> conn / as sysdba
Connected.
SQL> alter system set sql92_security=false scope=spfile;

System altered.

SQL> startup force
ORACLE instance started.

Total System Global Area 2147481656 bytes
Fixed Size                  8898616 bytes
Variable Size             553648128 bytes
Database Buffers         1577058304 bytes
Redo Buffers                7876608 bytes
Database mounted.
Database opened.
SQL> show parameter sql92

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sql92_security                       boolean     FALSE
SQL> conn u1/u1
Connected.
SQL> insert into bp.xtest values(null);
insert into bp.xtest values(null)
                            *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("BP"."TEST"."C1")
| improve this answer | |
2

There is a security consequence to setting SQL92_SECURITY to false.

From https://www.stigviewer.com/stig/oracle_database_12c/2020-04-01/finding/V-61429

The configuration option SQL92_SECURITY specifies whether table-level SELECT privileges are required to execute an update or delete that references table column values. If this option is disabled (set to FALSE), the UPDATE privilege can be used to determine values that should require SELECT privileges. The SQL92_SECURITY setting of TRUE prevents the exploitation of user credentials with only DELETE or UPDATE privileges on a table from being able to derive column values in that table by performing a series of update/delete statements using a where clause, and rolling back the change.

In the following example, with SQL92_SECURITY set to FALSE, a user with only delete privilege on the scott.emp table is able to derive that there is one employee with a salary greater than 3000. With SQL92_SECURITY set to TRUE, that user is prevented from attempting to derive a value.

SQL92_SECURITY = FALSE

SQL> delete from scott.emp where sal > 3000; 

1 row deleted 

SQL> rollback; 

Rollback complete 

SQL92_SECURITY = TRUE

SQL> delete from scott.emp where sal > 3000; 

delete from scott.emp where sal > 3000 * 

ERROR at line 1: ORA-01031: insufficient privileges

If this is a concern for you, then consider using a PL/SQL API package to make changes to your table, rather than granting access directly to the user. See "Guarding Your Data Behind a Hard Shell PL/SQL API" for reference. Also see here: https://www.youtube.com/watch?reload=9&v=GZUgey3hwyI. A singleton package with definers rights could raise the error back to the app without granting excessive privileges or altering the overall security posture of your system.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.