From e07b7a8b935c304bf6cf868978038e14e2b4ce9f Mon Sep 17 00:00:00 2001 From: =?utf8?q?cat=20=C3=A6scling?= <11325618-aescling@users.noreply.gitlab.com> Date: Tue, 25 Jul 2023 20:33:13 -0400 Subject: [PATCH] Protect headers we always send from override The extensibility is not great because execline makes lists difficult. There are no native lists, not to mention any kind of list.contains --- README.md | 4 +++- .../binaries/http-print-header-files.execline | 22 ++++++++++--------- visible-to-httpd/binaries/httpd.execline | 9 +++++++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a209adc..a53e7f1 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,9 @@ scheme, and a `Content-Type` file, to override any other mechanism for determining the Content-Type to send to the client. Note that a `Content-Type` file in the `headers` folder is always -ignored. +ignored. This is also true for the other required or recommended +HTTP 1.1 headers always sent by httpd.execline, namely +`Content-Length`, `Date`, and `Last-Modified`. a former official website for `httpd-execline.eerie.garden` used to redirect to this github repository, thanks to diff --git a/visible-to-httpd/binaries/http-print-header-files.execline b/visible-to-httpd/binaries/http-print-header-files.execline index 9886081..3b5980a 100755 --- a/visible-to-httpd/binaries/http-print-header-files.execline +++ b/visible-to-httpd/binaries/http-print-header-files.execline @@ -6,7 +6,7 @@ # instances of ${hostname} and ${resource} are substituted with the provided # host and resource from the request # -# the script will refuse to override the Content-Type header +# the script will refuse to override any header already set by httpd.execline # # execs into self in order to retain an environment variable which marks # whether a certain header has been overridden or not @@ -30,15 +30,20 @@ emptyenv -P # performs `basename ${header_file}` backtick -E -n header_name { pipeline { s6-echo -n -- ${header_file} } - sed "s@.*/([^/]*)@\\1@" + pipeline { sed "s@.*/([^/]*)@\\1@" } + tr -d " \t\r\n" # paranoid } +# ignore protected headers ifelse { - pipeline { s6-echo -n -- \${header_name} } - grep -s -i '^[ ]*Content-Type[ ]*$' # paranoid whitespace matching + backtick -E -n header_name_lowercase { + pipeline { s6-echo -n -- ${header_name} } + tr A-Z a-z + } + s6-test -v httpd_execline_protected_header_${header_name_lowercase} } { - foreground { log.execline "refusing to override Content-Type header" } + foreground { log.execline "WARNING: configuration error: ignoring protected header: \""${header_name}\" } http-print-header-directories.execline ${@} } @@ -63,12 +68,9 @@ define header_substitution_script } s6-echo -n -- " -# we’ll strip out `\r`s and `\n`s from filenames and file contents, in +# we’ll strip out `\r`s and `\n`s from file contents, in # case the configuration should ever be made in a mischevious way -if { - pipeline { s6-echo -n -- ${header_name}": " } - tr -d "\r\n" -} +if { s6-echo -n -- ${header_name}": " } if { backtick -E -n unparsed_header_contents { pipeline { cat ${header_file} } diff --git a/visible-to-httpd/binaries/httpd.execline b/visible-to-httpd/binaries/httpd.execline index 275f895..3134664 100755 --- a/visible-to-httpd/binaries/httpd.execline +++ b/visible-to-httpd/binaries/httpd.execline @@ -217,7 +217,14 @@ if -X -n -t { # Security Policy; for the latter, consider HTTP 301 redirects # # be warned!! we do not validate these overrides! - backtick -n extra_headers { http-get-extra-headers.execline } + backtick -n extra_headers { + export httpd_execline_protected_header_content-length "" + export httpd_execline_protected_header_content-type "" + export httpd_execline_protected_header_date "" + export httpd_execline_protected_header_last-modified "" + + http-get-extra-headers.execline + } backtick -D "200 ok" -n status_code_and_message { if { s6-test -r configuration/overrides/${resource}/status_code } -- 2.47.3