@@ -1247,3 +1247,258 @@ SELECT * FROM toyemp WHERE name = 'sharon';
1247
1247
sharon | 25 | (15,12) | 12000
1248
1248
(1 row)
1249
1249
1250
+ --
1251
+ -- Test for Leaky view scenario
1252
+ --
1253
+ CREATE USER alice;
1254
+ CREATE FUNCTION f_leak (text)
1255
+ RETURNS bool LANGUAGE 'plpgsql' COST 0.0000001
1256
+ AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END';
1257
+ CREATE TABLE customer (
1258
+ cid int primary key,
1259
+ name text not null,
1260
+ tel text,
1261
+ passwd text
1262
+ );
1263
+ NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "customer_pkey" for table "customer"
1264
+ CREATE TABLE credit_card (
1265
+ cid int references customer(cid),
1266
+ cnum text,
1267
+ climit int
1268
+ );
1269
+ CREATE TABLE credit_usage (
1270
+ cid int references customer(cid),
1271
+ ymd date,
1272
+ usage int
1273
+ );
1274
+ INSERT INTO customer
1275
+ VALUES (101, 'alice', '+81-12-3456-7890', 'passwd123'),
1276
+ (102, 'bob', '+01-234-567-8901', 'beafsteak'),
1277
+ (103, 'eve', '+49-8765-43210', 'hamburger');
1278
+ INSERT INTO credit_card
1279
+ VALUES (101, '1111-2222-3333-4444', 4000),
1280
+ (102, '5555-6666-7777-8888', 3000),
1281
+ (103, '9801-2345-6789-0123', 2000);
1282
+ INSERT INTO credit_usage
1283
+ VALUES (101, '2011-09-15', 120),
1284
+ (101, '2011-10-05', 90),
1285
+ (101, '2011-10-18', 110),
1286
+ (101, '2011-10-21', 200),
1287
+ (101, '2011-11-10', 80),
1288
+ (102, '2011-09-22', 300),
1289
+ (102, '2011-10-12', 120),
1290
+ (102, '2011-10-28', 200),
1291
+ (103, '2011-10-15', 480);
1292
+ CREATE VIEW my_property_normal AS
1293
+ SELECT * FROM customer WHERE name = current_user;
1294
+ CREATE VIEW my_property_secure WITH (security_barrier) AS
1295
+ SELECT * FROM customer WHERE name = current_user;
1296
+ CREATE VIEW my_credit_card_normal AS
1297
+ SELECT * FROM customer l NATURAL JOIN credit_card r
1298
+ WHERE l.name = current_user;
1299
+ CREATE VIEW my_credit_card_secure WITH (security_barrier) AS
1300
+ SELECT * FROM customer l NATURAL JOIN credit_card r
1301
+ WHERE l.name = current_user;
1302
+ CREATE VIEW my_credit_card_usage_normal AS
1303
+ SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r;
1304
+ CREATE VIEW my_credit_card_usage_secure WITH (security_barrier) AS
1305
+ SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r;
1306
+ GRANT SELECT ON my_property_normal TO public;
1307
+ GRANT SELECT ON my_property_secure TO public;
1308
+ GRANT SELECT ON my_credit_card_normal TO public;
1309
+ GRANT SELECT ON my_credit_card_secure TO public;
1310
+ GRANT SELECT ON my_credit_card_usage_normal TO public;
1311
+ GRANT SELECT ON my_credit_card_usage_secure TO public;
1312
+ --
1313
+ -- Run leaky view scenarios
1314
+ --
1315
+ SET SESSION AUTHORIZATION alice;
1316
+ --
1317
+ -- scenario: if a qualifier with tiny-cost is given, it shall be launched
1318
+ -- prior to the security policy of the view.
1319
+ --
1320
+ SELECT * FROM my_property_normal WHERE f_leak(passwd);
1321
+ NOTICE: f_leak => passwd123
1322
+ NOTICE: f_leak => beafsteak
1323
+ NOTICE: f_leak => hamburger
1324
+ cid | name | tel | passwd
1325
+ -----+-------+------------------+-----------
1326
+ 101 | alice | +81-12-3456-7890 | passwd123
1327
+ (1 row)
1328
+
1329
+ EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd);
1330
+ QUERY PLAN
1331
+ ------------------------------------------------------------------
1332
+ Seq Scan on customer
1333
+ Filter: (f_leak(passwd) AND (name = ("current_user"())::text))
1334
+ (2 rows)
1335
+
1336
+ SELECT * FROM my_property_secure WHERE f_leak(passwd);
1337
+ NOTICE: f_leak => passwd123
1338
+ cid | name | tel | passwd
1339
+ -----+-------+------------------+-----------
1340
+ 101 | alice | +81-12-3456-7890 | passwd123
1341
+ (1 row)
1342
+
1343
+ EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd);
1344
+ QUERY PLAN
1345
+ ---------------------------------------------------
1346
+ Subquery Scan on my_property_secure
1347
+ Filter: f_leak(my_property_secure.passwd)
1348
+ -> Seq Scan on customer
1349
+ Filter: (name = ("current_user"())::text)
1350
+ (4 rows)
1351
+
1352
+ --
1353
+ -- scenario: if a qualifier references only one-side of a particular join-
1354
+ -- tree, it shall be distributed to the most deep scan plan as
1355
+ -- possible as we can.
1356
+ --
1357
+ SELECT * FROM my_credit_card_normal WHERE f_leak(cnum);
1358
+ NOTICE: f_leak => 1111-2222-3333-4444
1359
+ NOTICE: f_leak => 5555-6666-7777-8888
1360
+ NOTICE: f_leak => 9801-2345-6789-0123
1361
+ cid | name | tel | passwd | cnum | climit
1362
+ -----+-------+------------------+-----------+---------------------+--------
1363
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000
1364
+ (1 row)
1365
+
1366
+ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum);
1367
+ QUERY PLAN
1368
+ ---------------------------------------------------------
1369
+ Hash Join
1370
+ Hash Cond: (r.cid = l.cid)
1371
+ -> Seq Scan on credit_card r
1372
+ Filter: f_leak(cnum)
1373
+ -> Hash
1374
+ -> Seq Scan on customer l
1375
+ Filter: (name = ("current_user"())::text)
1376
+ (7 rows)
1377
+
1378
+ SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
1379
+ NOTICE: f_leak => 1111-2222-3333-4444
1380
+ cid | name | tel | passwd | cnum | climit
1381
+ -----+-------+------------------+-----------+---------------------+--------
1382
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000
1383
+ (1 row)
1384
+
1385
+ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
1386
+ QUERY PLAN
1387
+ ---------------------------------------------------------------
1388
+ Subquery Scan on my_credit_card_secure
1389
+ Filter: f_leak(my_credit_card_secure.cnum)
1390
+ -> Hash Join
1391
+ Hash Cond: (r.cid = l.cid)
1392
+ -> Seq Scan on credit_card r
1393
+ -> Hash
1394
+ -> Seq Scan on customer l
1395
+ Filter: (name = ("current_user"())::text)
1396
+ (8 rows)
1397
+
1398
+ --
1399
+ -- scenario: an external qualifier can be pushed-down by in-front-of the
1400
+ -- views with "security_barrier" attribute
1401
+ --
1402
+ SELECT * FROM my_credit_card_usage_normal
1403
+ WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
1404
+ NOTICE: f_leak => 1111-2222-3333-4444
1405
+ cid | name | tel | passwd | cnum | climit | ymd | usage
1406
+ -----+-------+------------------+-----------+---------------------+--------+------------+-------
1407
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 10-05-2011 | 90
1408
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 10-18-2011 | 110
1409
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 10-21-2011 | 200
1410
+ (3 rows)
1411
+
1412
+ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal
1413
+ WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
1414
+ QUERY PLAN
1415
+ ------------------------------------------------------------------------------
1416
+ Nested Loop
1417
+ Join Filter: (l.cid = r.cid)
1418
+ -> Seq Scan on credit_usage r
1419
+ Filter: ((ymd >= '10-01-2011'::date) AND (ymd < '11-01-2011'::date))
1420
+ -> Materialize
1421
+ -> Subquery Scan on l
1422
+ Filter: f_leak(l.cnum)
1423
+ -> Hash Join
1424
+ Hash Cond: (r.cid = l.cid)
1425
+ -> Seq Scan on credit_card r
1426
+ -> Hash
1427
+ -> Seq Scan on customer l
1428
+ Filter: (name = ("current_user"())::text)
1429
+ (13 rows)
1430
+
1431
+ SELECT * FROM my_credit_card_usage_secure
1432
+ WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
1433
+ NOTICE: f_leak => 1111-2222-3333-4444
1434
+ NOTICE: f_leak => 1111-2222-3333-4444
1435
+ NOTICE: f_leak => 1111-2222-3333-4444
1436
+ NOTICE: f_leak => 1111-2222-3333-4444
1437
+ NOTICE: f_leak => 1111-2222-3333-4444
1438
+ cid | name | tel | passwd | cnum | climit | ymd | usage
1439
+ -----+-------+------------------+-----------+---------------------+--------+------------+-------
1440
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 10-05-2011 | 90
1441
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 10-18-2011 | 110
1442
+ 101 | alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 10-21-2011 | 200
1443
+ (3 rows)
1444
+
1445
+ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure
1446
+ WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
1447
+ QUERY PLAN
1448
+ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1449
+ Subquery Scan on my_credit_card_usage_secure
1450
+ Filter: (f_leak(my_credit_card_usage_secure.cnum) AND (my_credit_card_usage_secure.ymd >= '10-01-2011'::date) AND (my_credit_card_usage_secure.ymd < '11-01-2011'::date))
1451
+ -> Hash Join
1452
+ Hash Cond: (r.cid = l.cid)
1453
+ -> Seq Scan on credit_usage r
1454
+ -> Hash
1455
+ -> Hash Join
1456
+ Hash Cond: (r.cid = l.cid)
1457
+ -> Seq Scan on credit_card r
1458
+ -> Hash
1459
+ -> Seq Scan on customer l
1460
+ Filter: (name = ("current_user"())::text)
1461
+ (12 rows)
1462
+
1463
+ --
1464
+ -- Test for the case when security_barrier gets changed between rewriter
1465
+ -- and planner stage.
1466
+ --
1467
+ PREPARE p1 AS SELECT * FROM my_property_normal WHERE f_leak(passwd);
1468
+ PREPARE p2 AS SELECT * FROM my_property_secure WHERE f_leak(passwd);
1469
+ EXECUTE p1;
1470
+ NOTICE: f_leak => passwd123
1471
+ NOTICE: f_leak => beafsteak
1472
+ NOTICE: f_leak => hamburger
1473
+ cid | name | tel | passwd
1474
+ -----+-------+------------------+-----------
1475
+ 101 | alice | +81-12-3456-7890 | passwd123
1476
+ (1 row)
1477
+
1478
+ EXECUTE p2;
1479
+ NOTICE: f_leak => passwd123
1480
+ cid | name | tel | passwd
1481
+ -----+-------+------------------+-----------
1482
+ 101 | alice | +81-12-3456-7890 | passwd123
1483
+ (1 row)
1484
+
1485
+ RESET SESSION AUTHORIZATION;
1486
+ ALTER VIEW my_property_normal SET (security_barrier=true);
1487
+ ALTER VIEW my_property_secure SET (security_barrier=false);
1488
+ SET SESSION AUTHORIZATION alice;
1489
+ EXECUTE p1; -- To be perform as a view with security-barrier
1490
+ NOTICE: f_leak => passwd123
1491
+ cid | name | tel | passwd
1492
+ -----+-------+------------------+-----------
1493
+ 101 | alice | +81-12-3456-7890 | passwd123
1494
+ (1 row)
1495
+
1496
+ EXECUTE p2; -- To be perform as a view without security-barrier
1497
+ NOTICE: f_leak => passwd123
1498
+ NOTICE: f_leak => beafsteak
1499
+ NOTICE: f_leak => hamburger
1500
+ cid | name | tel | passwd
1501
+ -----+-------+------------------+-----------
1502
+ 101 | alice | +81-12-3456-7890 | passwd123
1503
+ (1 row)
1504
+
0 commit comments