Database administrators often treat a SQL connection as a channel for data, not as a route to the operating-system account that runs the database. PostgreSQL's COPY ... PROGRAM breaks that assumption. The server runs the command supplied in the statement, so the effective privileges are those of the PostgreSQL server process, not those of the client that sent the SQL.
The PostgreSQL documentation is direct about the risk. A file name or command in COPY is allowed only for superusers or roles granted pg_read_server_files, pg_write_server_files, or pg_execute_server_program. Those roles are administrative capabilities, not ordinary import helpers. A team that grants one to an application role has given that role a path to files and programs reachable by the database service.
Where the trust boundary sits
An import workflow may look harmless from the application's side. The application receives a CSV file, sends a query, and expects rows to appear in a staging table. If the query contains a program invocation assembled from user-controlled values, the database can become the execution point. Shell metacharacters, command substitution, and programs that read additional configuration are reasons to avoid any dynamic command construction.
The documentation recommends a fixed command string and warns against including user input. A fixed command still needs review. A wrapper that calls a shell, a Python interpreter, or a utility with a configuration file may widen the effect of a small SQL change. The PostgreSQL service account may also read data that the application process cannot, including backups or environment-specific files.
Controls that match the capability
Treat pg_execute_server_program as highly privileged. Inventory role memberships and remove the role from application accounts that only need to load files from a client. Use client-side \copy or a bounded application import service when the database does not need server-side program execution. If server-side import is required, deploy a dedicated wrapper with a fixed argument list, place it in a directory that the database account can execute but not modify, and log its invocations.
Separate the database's operating-system account from other services. Give it only the files and directories needed for its work, and avoid running it with access to secret stores, build workspaces, or broad home directories. Use SELinux or another mandatory access-control layer where available. Test the boundary by confirming that a low-privilege database role cannot invoke COPY ... PROGRAM and that the service account cannot read an unrelated canary file.
The limitation is important. PostgreSQL role separation does not protect against a compromised superuser, and a fixed command can still be abused if the called program accepts dangerous options. The control is an explicit privilege boundary, backed by least privilege and testing, rather than a guarantee that SQL imports are safe.
References
PostgreSQL Global Development Group, COPY