Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

[Bug] Non-superuser can bypass the external-table protocol privilege check via utility-mode connections

Đang mở
#1,992 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
72/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c, postgresql
Lĩnh vực
databases, security

Hướng nghiên cứu

Bắt đầu với gpcontrib/gp_exttable_fdw/option.c và xem xét gp_exttable_permission_check(), sau đó kiểm tra check_gp_role() trong src/backend/cdb/cdbvars.c để hiểu đường đi utility-mode có thể tiếp cận. Thêm kiểm thử hồi quy trong src/test/isolation2/input/external_table.source cho việc tạo bảng file:// và gpfdist:// ở utility-mode bởi người dùng không có đặc quyền; được xem là hoàn tất khi cả hai đều bị từ chối và không có relation nào xuất hiện trong pg_class.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

type: Bug type: Security
Apache Cloudberry version

Affected: 2.1.0-incubating and earlier, and current main (verified on c781604c5ba).

What happened

The privilege check that enforces "only a superuser may create a file:// external table"
is skipped entirely when the session runs in utility mode.

In gpcontrib/gp_exttable_fdw/option.c, gp_exttable_permission_check() gates the whole
check block on the dispatch role:

if (!is_superuser && Gp_role == GP_ROLE_DISPATCH)
{
    /*
     * - Never allow 'file' exttables if not superuser.
     * - Allow http, gpfdist or gpfdists tables if pg_auth has the right
     *   permissions for this role and for this type of table
     */
    is_valid_locationuris(location_list, is_writable);
    ...
}

Under Gp_role == GP_ROLE_UTILITY the condition is false, so neither the file://
superuser restriction nor the gpfdist/gpfdists pg_authid privilege checks
(rolcreaterexthttp, rolcreaterextgpfd, rolcreatewextgpfd) ever run.

The role is reachable by an unprivileged user: gp_role is a PGC_BACKEND GUC, and
its validator check_gp_role() (src/backend/cdb/cdbvars.c) has no superuser gate —
it only forbids upgrading an already-assigned role. A client can therefore request
utility mode in the startup packet (PGOPTIONS='-c gp_role=utility') as an ordinary
login role.

The resulting table is a normal catalog entry. Once created in a utility-mode session,
it can be read from an ordinary dispatch session, so the attacker gets arbitrary
server-side file reads with the privileges of the OS account running the database
(/etc/passwd, pg_hba.conf, postgresql.conf, key material, WAL and data files, …).

What you think should happen instead

The file:// protocol restriction — and the pg_authid protocol privileges for
gpfdist/gpfdists — are security boundaries and must hold in every connection mode
a user can reach. gp_role is a transport/topology setting, not an authorization
level, so it must not be able to turn a privilege check off.

How to reproduce
# 1. As a superuser, create an unprivileged login role.
psql -p 7000 -c "CREATE ROLE lowpriv LOGIN;"

# 2. Connect as that role in utility mode and create a file:// external table.
PGOPTIONS='-c gp_role=utility' psql -p 7000 -U lowpriv -d postgres <<'SQL'
SELECT current_setting('gp_role');   -- utility
SELECT current_setting('is_superuser');  -- off
CREATE READABLE EXTERNAL TABLE etc_passwd (data text)
  LOCATION ('file://localhost/etc/passwd') FORMAT 'TEXT';
SQL
# Expected: ERROR: must be superuser to create an external table with a file protocol
# Actual:   CREATE EXTERNAL TABLE

# 3. Read it back from an ordinary (dispatch) session as the same unprivileged role.
psql -p 7000 -U lowpriv -d postgres -c "SELECT * FROM etc_passwd;"

The same bypass applies to gpfdist:// / gpfdists:// locations for a role that lacks
rolcreaterextgpfd, and to the http:// protocol for a role that lacks rolcreaterexthttp.

Operating System

Rocky Linux 9.6 (Blue Onyx). Not OS-specific.

Anything else

Impact. CVSS v3.1 6.5 Medium
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. Reproducible every time; no race, no special
cluster configuration. This is not by design: the superuser-only restriction on
file:// is documented and is simply not reached in utility mode.

Proposed fix. Run the check in utility mode as well:

-    if(!is_superuser && Gp_role == GP_ROLE_DISPATCH)
+    if(!is_superuser &&
+       (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY))

GP_ROLE_EXECUTE is deliberately left out. That role is only ever set by the internal
dispatch handshake and cannot be forged through PGOPTIONS, so excluding it closes the
hole without re-validating DDL on the segments that the coordinator has already checked.

Test coverage. A regression case belongs in
src/test/isolation2/input/external_table.source: from a -1U (utility) session,
SET SESSION AUTHORIZATION to a non-superuser role and assert that both a file://
and an unprivileged gpfdist:// CREATE READABLE EXTERNAL TABLE are rejected, then
assert nothing was created in pg_class.

Credit. Reported to security@apache.org by Geo (cve@sageby.com); triaged and
accepted by the Apache Cloudberry PMC. Back-ports to affected release branches to follow.

  • Yes, I am willing to submit a PR!
Ngôn ngữ chính
C
Star
1.4k
Fork
248
Merge trung bình
4 ngày 10 giờ
Pull request đã merge (30 ngày)
40

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của apache/cloudberry

Tất cả issue của apache/cloudberry

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.