diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Add security and fork-behaviour regression testsv2.0.0
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/t0200-security.sh | 113 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 file changed, 113 insertions, 0 deletions
diff --git a/tests/t0200-security.sh b/tests/t0200-security.sh new file mode 100644 index 0000000..221b56b --- /dev/null +++ b/tests/t0200-security.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +test_description='Check security fixes and fork-specific behavior' +. ./setup.sh + +# A repo with an oversized blob, readmes that carry markup, and a directory, +# plus a config that pins a tiny blob limit and groups directories. +test_expect_success 'set up security fixtures' ' + mkrepo repos/sec 1 && + ( + cd repos/sec && + dd if=/dev/zero bs=1024 count=4 2>/dev/null | tr "\0" "X" >big.txt && + printf "# Title\n<script>alert(1)</script>\n" >README.md && + printf "<script>alert(2)</script>\n" >readme.txt && + printf "top\n" >afile && + mkdir zsub && + printf "inner\n" >zsub/inner && + git add -A && + git commit -m fixtures + ) && + { + echo "virtual-root=/" && + echo "cache-size=0" && + echo "max-blob-size=1" && + echo "enable-blame=1" && + echo "enable-tree-group-dirs=1" && + echo "repo.url=sec" && + echo "repo.path=$PWD/repos/sec/.git" + } >seccgitrc +' + +secq() { CGIT_CONFIG="$PWD/seccgitrc" QUERY_STRING="$1" cgit; } + +# --- Argument injection through the log id= parameter ----------------------- +# A tip beginning with a dash would be parsed as a git option, and +# id=--output=<path> would create or truncate an arbitrary file. +test_expect_success 'log id=--output does not write a file' ' + rm -f pwned && + cgit_query "url=foo/log&id=--output=$PWD/pwned" >tmp 2>&1 && + ! test -e pwned +' + +test_expect_success 'log id=--output is rejected as an invalid revision' ' + grep -i "invalid revision" tmp +' + +test_expect_success 'a normal log still renders' ' + cgit_query "url=foo/log" >tmp && + grep -i "commit 5" tmp +' + +test_expect_success 'a valid id= still renders the log' ' + sha=$(git -C repos/foo rev-parse HEAD) && + cgit_query "url=foo/log&id=$sha" >tmp && + grep -i "commit 5" tmp +' + +# --- max-blob-size is enforced before the object is read -------------------- +test_expect_success 'tree view refuses an oversized blob' ' + secq "url=sec/tree/big.txt" | grep -iE "exceeds|too large" +' + +test_expect_success 'plain view refuses an oversized blob' ' + secq "url=sec/plain/big.txt" | grep -iE "exceeds|too large|413" +' + +test_expect_success 'blame view refuses an oversized blob' ' + secq "url=sec/blame/big.txt" | grep -iE "exceeds|too large" +' + +test_expect_success 'a small blob is still served' ' + secq "url=sec/plain/afile" | grep -F "top" +' + +# --- Readme rendering escapes untrusted repository content ------------------ +test_expect_success 'markdown readme is escaped and marked for the client' ' + { + echo "virtual-root=/" && + echo "cache-size=0" && + echo "repo.url=md" && + echo "repo.path=$PWD/repos/sec/.git" && + echo "repo.readme=master:README.md" + } >secmdrc && + CGIT_CONFIG="$PWD/secmdrc" QUERY_STRING="url=md/about/" cgit >tmp && + grep "data-markdown" tmp && + grep "<script>" tmp && + ! grep "<script>alert(1)</script>" tmp +' + +test_expect_success 'non-markdown readme without a filter is escaped' ' + { + echo "virtual-root=/" && + echo "cache-size=0" && + echo "repo.url=txt" && + echo "repo.path=$PWD/repos/sec/.git" && + echo "repo.readme=master:readme.txt" + } >sectxtrc && + CGIT_CONFIG="$PWD/sectxtrc" QUERY_STRING="url=txt/about/" cgit >tmp && + grep "<script>" tmp && + ! grep "<script>alert(2)</script>" tmp +' + +# --- Fork feature: directories are grouped before files in the tree --------- +test_expect_success 'tree groups directories before files' ' + secq "url=sec/tree/" >tmp && + dirline=$(grep -n "tree/zsub" tmp | head -1 | cut -d: -f1) && + fileline=$(grep -n "tree/afile" tmp | head -1 | cut -d: -f1) && + test -n "$dirline" && + test -n "$fileline" && + test "$dirline" -lt "$fileline" +' + +test_done |
