summaryrefslogtreecommitdiff
path: root/yhttpd/src/maps/hashmap.tmpl
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-30 14:20:00 +0300
committerPaul Buetow <paul@buetow.org>2026-06-30 14:20:00 +0300
commite4de236e355b16a849b086f0ac1bf3b2c2d4964b (patch)
treeb7bbbd1032fbda6bd74b77f79fb8bb810b49ba53 /yhttpd/src/maps/hashmap.tmpl
parentdadd9f9cb076688f0377840dcc657484de773391 (diff)
Fix CGI command injection: execve instead of popen (no shell)
tool::shell_command (the CGI executor, only called from reqp when httpd.enablecgi=true and the request ends in .cgi) did popen(s_command, "r") = /bin/sh -c <templatedir+request>. The request path is URL- derived, so shell metacharacters (; | $() etc.) in the path were interpreted by the shell -> command injection / RCE the moment CGI is enabled. (Disabled by default; reqp's path-traversal guard (yr0) already prevents '..' escaping the template dir but does not filter metacharacters.) Replace popen with fork/execve of the file directly (no shell): - stat() the path; require a regular file. - pipe + fork; child dup2's stdout to the pipe, closes inherited fds (3..OPEN_MAX) so the CGI can't see/hold the listen socket or other client conns, then execve(path, [path, NULL], [NULL]) with an empty env; _exit(127) on exec failure. - parent reads the pipe to EOF (retrying on EINTR) then waitpid. s_command is passed by value, so the child's COW copy is safe to use post-fork. Verified with httpd.enablecgi=true: a /bin/sh CGI returns its output (CGI-OK); injection attempts sh.cgi;id / test.cgi$(id) / test.cgi|id return empty (no command execution); server stays up. With enablecgi=false (default) test.cgi is served as a static template and normal chat works. Independent review: APPROVE-WITH-NITS; the inherited-fd and EINTR nits were addressed; the remaining nits (empty envp/no RFC3875 vars, no CGI timeout, stat vs lstat) are acceptable for a dormant off-by-default feature and noted for if CGI is ever reactivated.
Diffstat (limited to 'yhttpd/src/maps/hashmap.tmpl')
0 files changed, 0 insertions, 0 deletions