From 17d0e41bef2044b55b324aaa160797cfbf2e915e Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 7 Nov 2026 17:55:48 -1000 Subject: Share the security tests' repeated setup --- tests/t0301-security.sh | 71 ++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 36 deletions(-) (limited to 'tests/t0301-security.sh') diff --git a/tests/t0301-security.sh b/tests/t0301-security.sh index 7260ab3..5a7f5fb 100755 --- a/tests/t0301-security.sh +++ b/tests/t0301-security.sh @@ -8,6 +8,25 @@ test_description='Check security fixes and fork-specific behaviour' . ./setup.sh +# Writes a config to the file named first, rooted at / with the cache off, +# holding the settings named after it in order, for a site cgitrc_repo cannot +# describe, a scan or more than one repository say. +cgitrc_site() { + cgitrc_site_file=$1 + shift + printf '%s\n' virtual-root=/ cache-size=0 "$@" >"$cgitrc_site_file" +} + +# Fails unless the response in the file named second opens with the status +# named first and carries no other, as a page that fails once its headers are +# out answers a second time below them. +expect_status() { + sed -n 1p "$2" >status-line && + test_grep "^Status: $1 " status-line && + grep "^Status:" "$2" >status-lines && + test_line_count = 1 status-lines +} + # The shipped server configs hand cgit the path as PATH_INFO, which the # server has already decoded, so a hostile byte arrives there raw rather # than through url=. @@ -48,7 +67,7 @@ test_expect_success 'set up security fixtures' ' test_expect_success 'log id=--output is refused without writing a file' ' cgitrc_copy nocacherc && cgit_rc nocacherc "url=foo/log&id=--output=$PWD/log-output" >tmp && - test_grep "^Status: 400" tmp && + expect_status 400 tmp && test_grep "
Invalid revision
" tmp && test_path_is_missing log-output ' @@ -70,16 +89,9 @@ test_expect_success 'a small blob is still served' ' # to reach the page escaped instead of as live markup, whatever its name # suggests about the format. test_expect_success 'markdown readme without a filter is escaped as plain text' ' - { - echo "virtual-root=/" && - echo "cache-size=0" && - echo "repo.url=md" && - echo "repo.path=$PWD/repos/sec/.git" && - echo "repo.readme=master:README.md" && - echo "repo.url=txt" && - echo "repo.path=$PWD/repos/sec/.git" && - echo "repo.readme=master:readme.txt" - } >secreadmerc && + cgitrc_site secreadmerc \ + repo.url=md "repo.path=$PWD/repos/sec/.git" repo.readme=master:README.md \ + repo.url=txt "repo.path=$PWD/repos/sec/.git" repo.readme=master:readme.txt && cgit_ok secreadmerc "url=md/about/" >tmp && test_grep "pre class=.plaintext.># Title$" tmp && test_grep "^<script>alert(1)</script>$" tmp && @@ -96,11 +108,7 @@ test_expect_success 'non-markdown readme without a filter is escaped as plain te # goes out as written, on an about page of its own. test_expect_success 'root-readme without a filter is its own page, as written' ' echo "site" >root.html && - { - echo "virtual-root=/" && - echo "cache-size=0" && - echo "root-readme=$PWD/root.html" - } >secrootrc && + cgitrc_site secrootrc "root-readme=$PWD/root.html" && cgit_rc secrootrc "url=" >tmp && grep "
  • about" tmp && ! grep "site" tmp && @@ -242,12 +250,7 @@ test_expect_success 'set up a submodule fixture with a hostile module-link' ' mkdir -p scan && cp -R repos/modlink scan/modlink && printf "module-link=/m/%%s/%%s/%%s/%%s/%%s/%%s/%%s/%%s/%%s/%%s\n" >scan/modlink/.git/cgitrc && - { - echo "virtual-root=/" && - echo "cache-size=0" && - echo "trust-scan-config=1" && - echo "scan-path=$PWD/scan" - } >modlinkrc + cgitrc_site modlinkrc trust-scan-config=1 "scan-path=$PWD/scan" ' test_expect_success 'a surplus conversion is shown literally, not filled' ' @@ -279,7 +282,7 @@ test_expect_success 'a doubled percent in a module-link renders as one' ' test_expect_success 'an unknown page under a repository answers 404 with its header' ' cgitrc_copy nocacherc && cgit_rc nocacherc "url=foo/nonsense/" >tmp && - test_grep "^Status: 404 Not Found" tmp && + expect_status 404 tmp && test_grep "Invalid request" tmp && test_grep "tmp && - grep "^Status: 200" tmp && + expect_status 200 tmp && ! grep "^X-Injected" tmp && grep "^Content-Disposition: inline; filename=.crlf\\\\r\\\\nX-Injected: 1.txt.$" tmp ' @@ -399,7 +402,7 @@ test_expect_success 'a posted length past any buffer is clamped' ' rm -f received && CGIT_CONFIG="$PWD/cverc" REQUEST_METHOD=POST CONTENT_LENGTH=$length \ QUERY_STRING="p=login" cgit tmp && - test_grep "^Status: 302" tmp && + expect_status 302 tmp && test $(cat received) = 4096 || return 1 done && CGIT_CONFIG="$PWD/cverc" REQUEST_METHOD=POST CONTENT_LENGTH=10 \ @@ -417,7 +420,7 @@ test_expect_success 'the dumb transport serves nothing but objects and packs' ' info/./alternates ./info/alternates info/Alternates /info/alternates do cgit_rc cverc "url=cve/objects/$path" >tmp && - test_grep "^Status: 404" tmp && + expect_status 404 tmp && test_grep ! -e repositoryformatversion -e repos/foo tmp || return 1 done && cgit_ok cverc "url=cve/HEAD" >tmp && @@ -429,7 +432,7 @@ test_expect_success 'the dumb transport serves nothing but objects and packs' ' test_expect_success 'the about page serves nothing above the readme directory' ' cgit_rc cverc "url=cve/about/../cverc" >tmp && - grep "^Status: 404" tmp && + expect_status 404 tmp && ! grep "virtual-root" tmp && cgit_rc cverc "url=cve/about/" >tmp && grep "readme text" tmp @@ -480,7 +483,7 @@ test_expect_success 'the advisory payloads fail the same way through PATH_INFO' for path in /cve/objects/../config /cve/objects/info/../../config /cve/about/../cverc do cgit_path cverc $path >tmp && - test_grep "^Status: 404" tmp && + expect_status 404 tmp && test_grep ! -e repositoryformatversion -e virtual-root tmp || return 1 done && cgit_ok_path cverc /cve/HEAD >tmp && @@ -514,12 +517,8 @@ test_expect_success 'a url opening with slashes links only below the site' ' # the policy alone. The cache listing prints keys visitors chose. test_expect_success 'repository bytes go out under a policy that loads nothing' ' mkrepo repos/svg 1 && - ( - cd repos/svg && - echo "" >x.svg && - git add x.svg && - git commit -m svg - ) && + test_commit -C repos/svg --no-tag svg x.svg \ + "" && cgitrc_repo svgrc svg mimetype.svg=image/svg+xml && cgit_ok svgrc "url=svg/plain/x.svg" >tmp && test_grep "^Content-Type: image/svg+xml;" tmp && @@ -653,7 +652,7 @@ test_expect_success 'a redirect keeps every query byte inside its Location' ' query=$(printf "x=a b\tc\r\nX-Injected: 1&y=\303\251\177") && cgit_rc redirectrc "url=foo/about&$query" >tmp && sed -n "1,/^\$/p" tmp >headers && - test_grep "^Status: 302" headers && + expect_status 302 headers && test_grep "^Location: /foo/?x=a%20b%09c%0D%0AX-Injected:%201&y=%C3%A9%7F$" headers && test_grep ! "^X-Injected" headers ' -- cgit 2.12.1