Improve shared app account scenario
Some checks failed
Repo Quality / structure (push) Has been cancelled

This commit is contained in:
2026-05-14 11:49:45 -03:00
parent 5fa6b34d1e
commit 77ecd70622
7 changed files with 220 additions and 53 deletions

View File

@@ -6,7 +6,7 @@ Show the risk of a technical application account used by many users and how the
## What This Lab Shows ## What This Lab Shows
Before Oracle Deep Data Security, a technical account or connection pool can query orders from every seller and region. After data grants are applied, the result depends on the persona propagated by the application. Before Oracle Deep Data Security, a technical account or connection pool can query orders from every seller and region. After data grants are applied, the database authorizes access based on the end-user persona, not only on the shared technical account.
## Personas ## Personas
@@ -16,39 +16,37 @@ Before Oracle Deep Data Security, a technical account or connection pool can que
## Where To Run The Commands ## Where To Run The Commands
Run commands from the repository root: Run SQL scripts from the repository root. On Linux/macOS/WSL:
```bash
cd ~/DEEP-DATA-SECURITY/oracle-deep-data-security-lab
export TNS_ADMIN=~/DEEP-DATA-SECURITY/wallet-ddslab
```
Connect as the lab administrator:
```bash
sql admin@ddslab_tunnel
```
SQLcl note: when running a script with `@file.sql`, press Enter once and wait for the output. Do not type `/` afterward, because `/` reruns the last command in the SQLcl buffer.
On Windows PowerShell:
```powershell ```powershell
cd C:\Users\rodrigo\Documents\Codex\oracle-deep-data-security-lab cd C:\Users\rodrigo\Documents\Codex\oracle-deep-data-security-lab
``` sql admin@ddslab_tunnel
Connect to the database with SQLcl or SQL*Plus:
```bash
sql "<connect_string>"
```
Example:
```text
ADMIN/<password>@ddslab_high
``` ```
## Step By Step - Before, Vulnerable Environment ## Step By Step - Before, Vulnerable Environment
1. Connect to the database: 1. Reset the scenario as `ADMIN`:
```bash
sql "<connect_string>"
```
2. Reset the scenario:
```sql ```sql
@scenarios/02-shared-app-account/sql/99_reset.sql @scenarios/02-shared-app-account/sql/99_reset.sql
``` ```
3. Create the table, data, users, and technical account: 2. Create the orders table, seed data, business personas, and the shared app account:
```sql ```sql
@scenarios/02-shared-app-account/sql/00_schema.sql @scenarios/02-shared-app-account/sql/00_schema.sql
@@ -56,34 +54,82 @@ ADMIN/<password>@ddslab_high
@scenarios/02-shared-app-account/sql/02_identities.sql @scenarios/02-shared-app-account/sql/02_identities.sql
``` ```
4. Simulate an application querying orders with broad SQL: 3. Show the full raw data as `ADMIN`:
```sql
SELECT order_id, customer_name, region, seller, amount, margin
FROM dds_orders
ORDER BY order_id;
```
4. Connect as the shared technical application account:
```bash
sql 'dds_app/AppPool#2026Lab!@ddslab_tunnel'
```
5. Run the broad application query:
```sql ```sql
@scenarios/02-shared-app-account/sql/04_test_queries.sql @scenarios/02-shared-app-account/sql/04_test_queries.sql
``` ```
Expected result before protection: orders from multiple regions and fields such as `MARGIN` may appear to users who should not see them. Expected result before protection: `DDS_APP` can see orders from all regions and the sensitive `MARGIN` column. This represents a common connection-pool problem where the database only sees the application account.
## Step By Step - After, With Deep Data Security ## Step By Step - After, With Deep Data Security
1. Apply the data grants: 1. Reconnect as `ADMIN` and apply the data grants:
```sql ```sql
@scenarios/02-shared-app-account/sql/03_data_grants.sql @scenarios/02-shared-app-account/sql/03_data_grants.sql
``` ```
2. Run the query again: 2. Connect as `alice`, a sales representative:
```sql ```bash
@scenarios/02-shared-app-account/sql/04_test_queries.sql sql 'alice/Welcome1_DDS!@ddslab_tunnel'
``` ```
3. Repeat the test by simulating `alice` and `bruno` as end users. 3. Run Alice's normal business query, without the sensitive `MARGIN` column:
```sql
ALTER SESSION SET CURRENT_SCHEMA = ADMIN;
SELECT order_id, customer_name, region, seller, amount
FROM dds_orders
ORDER BY order_id;
```
This query represents the normal sales workflow. Alice needs customer, region, seller, and order amount to follow her pipeline, but she does not need commercial margin.
4. Try to access the sensitive margin column as Alice:
```sql
SELECT order_id, customer_name, region, seller, amount, margin
FROM dds_orders
ORDER BY order_id;
```
This query represents an application bug, abused endpoint, prompt injection, or ad hoc SQL asking for a sensitive field outside Alice's business role.
5. Connect as `bruno`, the LATAM manager, and run the manager query:
```bash
sql 'bruno/Welcome1_DDS!@ddslab_tunnel'
```
```sql
ALTER SESSION SET CURRENT_SCHEMA = ADMIN;
SELECT order_id, customer_name, region, seller, amount, margin
FROM dds_orders
ORDER BY order_id;
```
Expected result after protection: Expected result after protection:
- `alice` sees only her orders and does not see `MARGIN`. - `alice` sees only her orders and does not get access to `MARGIN`.
- `bruno` sees LATAM orders with manager visibility. - `bruno` sees LATAM orders with manager visibility, including `MARGIN`.
- The technical account is no longer the only authorization boundary. - The technical account is no longer the only authorization boundary.
## Optional Automated Execution ## Optional Automated Execution
@@ -103,4 +149,3 @@ Linux/macOS:
## Demo Details ## Demo Details
See the complete walkthrough, evidence, and official references in [RUNBOOK.md](RUNBOOK.md). See the complete walkthrough, evidence, and official references in [RUNBOOK.md](RUNBOOK.md).

View File

@@ -18,13 +18,27 @@ Show that a shared technical application account should not be the real data aut
## Before - Vulnerable Environment ## Before - Vulnerable Environment
1. Reset the scenario: 1. From the repository root, connect as `ADMIN`:
```bash
cd ~/DEEP-DATA-SECURITY/oracle-deep-data-security-lab
export TNS_ADMIN=~/DEEP-DATA-SECURITY/wallet-ddslab
sql admin@ddslab_tunnel
```
Presenter note: `ADMIN` prepares the lab objects. The risk will be shown later using the shared application account.
SQLcl note: after running a script with `@file.sql`, do not type `/`. The slash reruns the last command in the SQLcl buffer and can make a successful command look like an error.
2. Reset the scenario:
```sql ```sql
@scenarios/02-shared-app-account/sql/99_reset.sql @scenarios/02-shared-app-account/sql/99_reset.sql
``` ```
2. Create the table, data, and technical account: Presenter note: this makes the demo repeatable and removes previous Data Grants or roles.
3. Create the table, data, and identities:
```sql ```sql
@scenarios/02-shared-app-account/sql/00_schema.sql @scenarios/02-shared-app-account/sql/00_schema.sql
@@ -32,12 +46,38 @@ Show that a shared technical application account should not be the real data aut
@scenarios/02-shared-app-account/sql/02_identities.sql @scenarios/02-shared-app-account/sql/02_identities.sql
``` ```
3. Simulate an application or API using the `DDS_APP` account to query all orders: Presenter note: `DDS_APP` represents the application connection pool; `alice` and `bruno` represent real business users.
4. Show all rows and columns as `ADMIN`:
```sql
SELECT order_id, customer_name, region, seller, amount, margin
FROM dds_orders
ORDER BY order_id;
```
Presenter note: `MARGIN` is commercially sensitive and should not be visible to every seller.
5. Exit and connect as the shared technical application account:
```sql
exit
```
```bash
sql 'dds_app/AppPool#2026Lab!@ddslab_tunnel'
```
Presenter note: this simulates a web app, API, BI tool, or AI service where many users arrive through the same database account.
6. Simulate an application or API using `DDS_APP` to query all orders:
```sql ```sql
@scenarios/02-shared-app-account/sql/04_test_queries.sql @scenarios/02-shared-app-account/sql/04_test_queries.sql
``` ```
Presenter note: before DDS, the database sees `DDS_APP` and the broad SQL returns too much data.
## Expected Result Before ## Expected Result Before
- The shared account can see orders from every seller and region. - The shared account can see orders from every seller and region.
@@ -46,18 +86,74 @@ Show that a shared technical application account should not be the real data aut
## After - Applying Deep Data Security ## After - Applying Deep Data Security
1. Apply data grants by business role: 1. Exit and reconnect as `ADMIN`:
```sql
exit
```
```bash
sql admin@ddslab_tunnel
```
2. Apply data grants by business role:
```sql ```sql
@scenarios/02-shared-app-account/sql/03_data_grants.sql @scenarios/02-shared-app-account/sql/03_data_grants.sql
``` ```
2. Run the same query in the context of `alice` and `bruno`: Presenter note: `seller_role` is limited to the seller's own rows and excludes `MARGIN`; `latam_manager_role` can see LATAM orders with full manager fields.
3. Test Alice, the sales representative, with a normal business query:
```sql ```sql
@scenarios/02-shared-app-account/sql/04_test_queries.sql exit
``` ```
```bash
sql 'alice/Welcome1_DDS!@ddslab_tunnel'
```
```sql
ALTER SESSION SET CURRENT_SCHEMA = ADMIN;
SELECT order_id, customer_name, region, seller, amount
FROM dds_orders
ORDER BY order_id;
```
Presenter note: this is Alice's legitimate workflow. She needs customer, region, seller, and amount to manage her pipeline, but she does not need commercial margin.
4. Try to force Alice to see `MARGIN`:
```sql
SELECT order_id, customer_name, region, seller, amount, margin
FROM dds_orders
ORDER BY order_id;
```
Presenter note: this simulates an application bug, abused API endpoint, prompt injection, or AI-generated SQL asking for a sensitive column outside Alice's business role.
5. Test Bruno, the LATAM manager:
```sql
exit
```
```bash
sql 'bruno/Welcome1_DDS!@ddslab_tunnel'
```
```sql
ALTER SESSION SET CURRENT_SCHEMA = ADMIN;
SELECT order_id, customer_name, region, seller, amount, margin
FROM dds_orders
ORDER BY order_id;
```
Presenter note: Bruno has manager visibility, so he can see LATAM orders and the margin needed for his role.
## Expected Result After ## Expected Result After
- `alice` sees only her orders and does not see `margin`. - `alice` sees only her orders and does not see `margin`.
@@ -76,4 +172,3 @@ Show that a shared technical application account should not be the real data aut
- Fine-Grained Data Authorization: https://docs.oracle.com/en/database/oracle/oracle-database/26/ddscg/fine-grained-data-authorization.html - Fine-Grained Data Authorization: https://docs.oracle.com/en/database/oracle/oracle-database/26/ddscg/fine-grained-data-authorization.html
- Create Data Grants: https://docs.oracle.com/en/database/oracle/oracle-database/26/ddscg/create-data-grants.html - Create Data Grants: https://docs.oracle.com/en/database/oracle/oracle-database/26/ddscg/create-data-grants.html
- End-User Security Contexts: https://docs.oracle.com/en/database/oracle/oracle-database/26/refrn/DBA_END_USER_SECURITY_CONTEXTS.html - End-User Security Contexts: https://docs.oracle.com/en/database/oracle/oracle-database/26/refrn/DBA_END_USER_SECURITY_CONTEXTS.html

View File

@@ -1,6 +1,16 @@
# Expected Results # Expected Results
- `alice` sees her orders and no `margin`. ## Before Oracle Deep Data Security
- `bruno` sees LATAM orders with all columns.
- The shared technical account alone is not the authorization boundary for data access.
- `DDS_APP` simulates a shared application account or connection pool.
- `DDS_APP` can query all orders from all regions.
- `DDS_APP` can see the sensitive `margin` column.
- The database cannot safely distinguish Alice's access from Bruno's access if the application account is the only security boundary.
## After Oracle Deep Data Security
- `alice` sees only her own orders.
- `alice` can query operational columns such as `order_id`, `customer_name`, `region`, `seller`, and `amount`.
- `alice` cannot access `margin`.
- `bruno` sees LATAM orders with manager visibility, including `margin`.
- The database enforces access based on the business persona, not only on the shared technical account.

View File

@@ -1,11 +1,20 @@
WHENEVER SQLERROR EXIT SQL.SQLCODE WHENEVER SQLERROR EXIT SQL.SQLCODE
CREATE TABLE dds_orders ( BEGIN
order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, EXECUTE IMMEDIATE q'[
customer_name VARCHAR2(100) NOT NULL, CREATE TABLE dds_orders (
region VARCHAR2(30) NOT NULL, order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
seller VARCHAR2(60) NOT NULL, customer_name VARCHAR2(100) NOT NULL,
amount NUMBER(12,2) NOT NULL, region VARCHAR2(30) NOT NULL,
margin NUMBER(12,2) NOT NULL seller VARCHAR2(60) NOT NULL,
); amount NUMBER(12,2) NOT NULL,
margin NUMBER(12,2) NOT NULL
)
]';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -955 THEN
RAISE;
END IF;
END;
/

View File

@@ -14,5 +14,11 @@ GRANT shared_app_session_role TO latam_manager_role;
GRANT DATA ROLE seller_role TO alice; GRANT DATA ROLE seller_role TO alice;
GRANT DATA ROLE latam_manager_role TO bruno; GRANT DATA ROLE latam_manager_role TO bruno;
CREATE USER dds_app IDENTIFIED BY "Welcome1_DDS_App!" ACCOUNT UNLOCK; CREATE USER dds_app IDENTIFIED BY "AppPool#2026Lab!" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO dds_app; GRANT CREATE SESSION TO dds_app;
-- Vulnerable baseline: this broad legacy role simulates a shared application
-- account or connection pool that can query the full table before DDS is enforced.
CREATE ROLE shared_app_legacy_access_role;
GRANT SELECT ON dds_orders TO shared_app_legacy_access_role;
GRANT shared_app_legacy_access_role TO dds_app;

View File

@@ -3,7 +3,7 @@ WHENEVER SQLERROR EXIT SQL.SQLCODE
CREATE OR REPLACE DATA GRANT seller_own_orders CREATE OR REPLACE DATA GRANT seller_own_orders
AS SELECT (order_id, customer_name, region, seller, amount) AS SELECT (order_id, customer_name, region, seller, amount)
ON dds_orders ON dds_orders
WHERE seller = ORA_END_USER_CONTEXT.username WHERE UPPER(seller) = ORA_END_USER_CONTEXT.username
TO seller_role; TO seller_role;
CREATE OR REPLACE DATA GRANT latam_manager_orders CREATE OR REPLACE DATA GRANT latam_manager_orders

View File

@@ -14,6 +14,8 @@ BEGIN EXECUTE IMMEDIATE 'DROP DATA ROLE latam_manager_role'; EXCEPTION WHEN OTHE
/ /
BEGIN EXECUTE IMMEDIATE 'DROP ROLE shared_app_session_role'; EXCEPTION WHEN OTHERS THEN NULL; END; BEGIN EXECUTE IMMEDIATE 'DROP ROLE shared_app_session_role'; EXCEPTION WHEN OTHERS THEN NULL; END;
/ /
BEGIN EXECUTE IMMEDIATE 'DROP ROLE shared_app_legacy_access_role'; EXCEPTION WHEN OTHERS THEN NULL; END;
/
BEGIN EXECUTE IMMEDIATE 'DROP END USER alice'; EXCEPTION WHEN OTHERS THEN NULL; END; BEGIN EXECUTE IMMEDIATE 'DROP END USER alice'; EXCEPTION WHEN OTHERS THEN NULL; END;
/ /
BEGIN EXECUTE IMMEDIATE 'DROP END USER bruno'; EXCEPTION WHEN OTHERS THEN NULL; END; BEGIN EXECUTE IMMEDIATE 'DROP END USER bruno'; EXCEPTION WHEN OTHERS THEN NULL; END;