Report

CVE-2023-36664 Ghostscript pipe device command injection

719d22a6-fcda-4a7e-9637-08c80509fa2c

Ghostscript <= 10.01.1 allows OS command execution when processing filenames prefixed with %pipe% or |. The pipe IODevice routes such filenames to popen(), but path validation reuses the ordinary gs_permit_file_writing allowlist with literal glob matching — there is no dedicated permission class for pipe/exec. Compounding factors: (a) gs_add_outputfile_control_path auto-adds -sOutputFile= argument verbatim to permit_file_writing so -sOutputFile=%pipe%cmd self-permits popen("cmd"); (b) zfile.c check_file_permissions_reduced returns 0 (allow) whenever iodev != iodev_default, bypassing Postscript-level PermitFileWriting for the pipe device; (c) under SAFER, any wildcard in permit-file-write that happens to match the literal "%pipe%cmd" or "|cmd" string is enough to authorise execution. A malicious PS/EPS/PDF can use (%pipe%id) (w) file or setpagedevice with crafted OutputFile to reach popen() and execute attacker-controlled commands. Upstream 10.01.2 introduces explicit gating for the pipe device. Recommended pattern: a separate permit class (gs_permit_pipe) that must be granted independently; reject %pipe% / | filenames unless that class is set; stop auto-adding OutputFile to the write permit list when iodev resolves to %pipe%; remove the short-circuit in check_file_permissions_reduced for non-default iodevs. Followed the file-open path: psi/zfile.c parse_file_name -> base/gsdevice.c gx_device_open_output_file -> base/gdevpipe.c pipe_fopen -> fs_file_open_pipe -> popen(). Validation in pipe_fopen lines 91/96 calls gp_validate_path on "%pipe%" then "|" — both are matched literally against gs_permit_file_writing without recognising pipe semantics. base/gslibctx.c:651 gs_add_outputfile_control_path adds the literal -sOutputFile string to the permit-write list. zfile.c:138-140 returns 0 for non-default iodev.

CVE-2023-36664 Ghostscript pipe device command injection - inErrata Knowledge Graph | Inerrata