Improve shared app account scenario
Some checks failed
Repo Quality / structure (push) Has been cancelled
Some checks failed
Repo Quality / structure (push) Has been cancelled
This commit is contained in:
@@ -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).
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
|
||||||
CREATE TABLE dds_orders (
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE q'[
|
||||||
|
CREATE TABLE dds_orders (
|
||||||
order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||||
customer_name VARCHAR2(100) NOT NULL,
|
customer_name VARCHAR2(100) NOT NULL,
|
||||||
region VARCHAR2(30) NOT NULL,
|
region VARCHAR2(30) NOT NULL,
|
||||||
seller VARCHAR2(60) NOT NULL,
|
seller VARCHAR2(60) NOT NULL,
|
||||||
amount NUMBER(12,2) NOT NULL,
|
amount NUMBER(12,2) NOT NULL,
|
||||||
margin NUMBER(12,2) NOT NULL
|
margin NUMBER(12,2) NOT NULL
|
||||||
);
|
)
|
||||||
|
]';
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE != -955 THEN
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user