Theo thứ tự nào PostgreSQL kiểm tra quyền đối tượng?


16

Với một vai trò cơ sở dữ liệu user1, một hàm something()được định nghĩa là một thủ tục được lưu trữ và một khung nhìn được tạo như sau:

CREATE VIEW view1 AS select * from something()

Và, được cấp quyền này:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

Khi tôi chạy SELECT * FROM view1, tôi gặp lỗi permission denied for function something().

Câu hỏi của tôi là, nếu tôi thu hồi các quyền chọn trên khung nhìn, tại sao hàm được gọi? Tôi đã mong đợi để nhận được một cái gì đó như:

permission denied for relation view1

Cảm ơn bạn!


2
AFAIK không có thứ tự xác định trong đó quyền được kiểm tra.
Craig Ringer

@CraigRinger Cảm ơn bạn! Tôi đoán đó là hành vi dự kiến ​​sau đó. Khi tôi hiển thị chế độ xem trong một api, tôi đã cố gắng tránh tiết lộ chi tiết triển khai của chế độ xem (đưa ra thông báo lỗi phàn nàn về các quyền của chức năng thay vì chế độ xem).
santios

1
Tôi nghi ngờ các quyền được đánh giá theo nhiều kế hoạch truy vấn thời trang giống nhau (ví dụ từ dưới lên) và như vậy đối tượng thấp nhất được đánh giá đầu tiên, trong trường hợp của bạn là something()hàm. Một thử nghiệm nhanh sẽ là sửa đổi truy vấn để bạn có được một kế hoạch giải thích khác, điều chỉnh các quyền phù hợp và sau đó xem liệu lỗi quyền được ném vào something()hàm hay nếu nó tuân theo cách đánh giá lại kế hoạch thực hiện mới.
John Eisbrener

Nếu bạn cấp quyền cho chức năng và thu hồi chúng trên chế độ xem, nó sẽ bỏ qua mọi đề cập đến chức năng cơ bản
amenadiel

Câu trả lời:


3

Vấn đề trong trường hợp đó không chính xác về thứ tự cấp phép, mà là thứ tự thực thi.

Trong sơ yếu lý lịch, cho PostgreSQL:

1- Chế độ xem đang truy cập bảng sẽ ghi đè quyền của bảng

2- Các chức năng xem, sẽ cần phải đánh giá tất cả các chức năng, trước khi được kiểm tra - vì vậy các chức năng phải được thực thi trước khi truy cập chế độ xem, ngay cả khi chế độ xem không có quyền chọn ...

Làm thế nào chúng ta có thể chứng minh điều đó?

Trong postgresql, các khung nhìn có thể cung cấp cho bạn quyền để thực hiện chọn trong bảng, ngay cả khi người dùng không có quyền này.

Ví dụ:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

Đăng nhập với tư cách người dùng 1:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

Trong trường hợp, người dùng sẽ có thể chọn view2 thậm chí không có quyền chọn bảng.

Nhưng nếu chúng ta làm điều tương tự với một chức năng thì sao? Các hành vi KHÔNG giống nhau. Hãy tạo một hàm chờ 5 giây trước khi trả về 1 (vì vậy chúng tôi có thể gỡ lỗi nếu postgresql chạy chức năng mỗi khi chúng tôi gọi chế độ xem)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

Đăng nhập với tư cách người dùng 1:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

Quyền được chọn trên chế độ xem không ghi đè quyền cho phép và thậm chí tệ nhất nếu chúng tôi thu hồi quyền từ view1, thông báo vẫn cho thấy postgresql dừng truy vấn của chúng tôi vì chức năng, bất kể quyền của chế độ xem là gì. (đó chính xác là những gì đang xảy ra trong câu hỏi)

Nhưng chức năng có thực sự được kiểm tra đầu tiên? Nếu chúng tôi cấp quyền 'tất cả' cho chức năng, nhưng thu hồi quyền xem ...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

Như bạn thấy postgresql WAITED 5 GIÂY trước khi nói rằng chúng tôi không có quyền xuất ra chế độ xem , cho thấy hàm " Something ()" được thực thi. Vì vậy, trả về dữ liệu chức năng phải tồn tại trước khi kiểm tra chế độ xem.

Vì vậy, bây giờ với các thử nghiệm này, bây giờ chúng tôi biết rằng PostgreSQL trước tiên cần đánh giá tất cả các chức năng trước khi tiếp tục truy vấn của chúng tôi, giống như truy vấn vẫn không tồn tại cho đến khi tất cả các chức năng được hoàn thành, vì vậy không thể giải quyết chế độ xem cho postgresql biết nếu chúng ta có hoặc không được phép chọn nó.

Tôi nghĩ điều này trả lời câu hỏi của bạn theo thuật ngữ "thứ tự cấp phép", nhưng tại sao postgresql cần đánh giá tất cả các chức năng trước khi tiếp tục, đó là một câu hỏi khác ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.