From ba872f126aa9416899b7114f8695f84ebbae6925 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Mon, 23 May 2022 19:33:08 +0200 Subject: [PATCH] avoid mishandling of pages (wrong 404 in particular) --- handlers/10_page.sh | 5 ++++- handlers/20_attachment.sh | 44 +++++++++++++++++++++------------------ handlers/30_edit.sh | 25 +++++++++++----------- handlers/90_brackets.sh | 11 ++++++++-- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/handlers/10_page.sh b/handlers/10_page.sh index 99b79a4..edb849a 100755 --- a/handlers/10_page.sh +++ b/handlers/10_page.sh @@ -36,6 +36,8 @@ wiki() { case "${PATH_INFO}" in /"[.]"/*) + # usually some file related to theme + # let file server handle errors FILE "${_EXEC}/${PATH_INFO#/\[.\]}" return 0 ;; @@ -49,7 +51,8 @@ case "${PATH_INFO}" in theme_error 400 return 0 ;; - */\[*\]/*) + */\[*\]/*|*/\[*\]) + # looks like some kind of handler return 1 ;; */) diff --git a/handlers/20_attachment.sh b/handlers/20_attachment.sh index efc66f1..63b42b4 100755 --- a/handlers/20_attachment.sh +++ b/handlers/20_attachment.sh @@ -66,13 +66,24 @@ attachment_convert(){ case ${PATH_INFO} in */\[attachment\]/) + # no trailing slash REDIRECT "${_BASE}${PATH_INFO%/}" ;; + */*/) + # attached files never end on / + return 1 + ;; */\[attachment\]) + # show attachment page + # receive uploads tsid="$(POST session_key)"; tsid="${tsid%% *}" attachment_delete="$(POST delete)" + page="${PATH_INFO%\[attachment\]}" - if [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ] && acl_write "${PATH_INFO%\[attachment\]}"; then + if [ ! -d "$_DATA/pages${page}" -a ! -d "$_DATA/pages${page}" ]; then + # base page does not exist + return 1 + elif [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ] && acl_write "${page}"; then . "$_EXEC/multipart.sh" multipart_cache @@ -87,10 +98,10 @@ case ${PATH_INFO} in return 0 fi - mkdir -p "$_DATA/pages/${PATH_INFO%/\[attachment\]}/#attachments/" + mkdir -p "$_DATA/pages${page}#attachments/" n=1; while filename=$(multipart_filename "file" "$n"); do filename="$(printf %s "$filename" |tr /\\0 __)" - multipart "file" "$n" >"$_DATA/pages/${PATH_INFO%/\[attachment\]}/#attachments/$filename" + multipart "file" "$n" >"$_DATA/pages${page}#attachments/$filename" n=$((n + 1)) done rm -- "$multipart_cachefile" @@ -101,17 +112,17 @@ case ${PATH_INFO} in head -c $((CONTENT_LENGTH)) >/dev/null return 0 elif [ "$attachment_delete" -a "$SESSION_ID" = "$tsid" ]; then - rm -- "$_DATA/pages/${PATH_INFO%/\[attachment\]}/#attachments/$attachment_delete" + rm -- "$_DATA/pages${page}#attachments/$attachment_delete" REDIRECT "${_BASE}${PATH_INFO}" elif [ "$attachment_delete" ]; then printf 'Refresh: %i\r\n' 4 theme_error 403 return 0 - elif acl_read "${PATH_INFO%\[attachment\]}"; then - theme_attachments "${PATH_INFO%\[attachment\]}" + elif ! acl_read "${page}"; then + theme_error 403 return 0 else - theme_error 404 + theme_attachments "${page}" return 0 fi ;; @@ -119,7 +130,9 @@ case ${PATH_INFO} in */\[attachment\]/*) attpath="${PATH_INFO%/\[attachment\]/*}/#attachments/${PATH_INFO##*/}" - if ! acl_read "${PATH_INFO%/\[attachment\]/*}"; then + if [ ! -f "$_DATA/pages/$attpath" -a ! -f "$_EXEC/pages/$attpath" ]; then + return 1 + elif ! acl_read "${PATH_INFO%/\[attachment\]/*}"; then theme_error 403 return 0 elif [ -f "$_DATA/pages/$attpath" ]; then @@ -128,18 +141,14 @@ case ${PATH_INFO} in elif [ -f "$_EXEC/pages/$attpath" ]; then FILE "$_EXEC/pages/$attpath" return 0 - else - theme_error 404 - return 0 fi ;; - */*/) - return 1 - ;; */*) attpath="${PATH_INFO%/*}/#attachments/${PATH_INFO##*/}" - if ! acl_read "${PATH_INFO%/*}/"; then + if [ ! -f "$_DATA/pages/$attpath" -a ! -f "$_EXEC/pages/$attpath" ]; then + return 1 + elif ! acl_read "${PATH_INFO%/*}/"; then theme_error 403 return 0 elif [ -f "$_DATA/pages/$attpath" ]; then @@ -148,11 +157,6 @@ case ${PATH_INFO} in elif [ -f "$_EXEC/pages/$attpath" ]; then FILE "$(attachment_convert "$_EXEC/pages/$attpath")" return 0 - elif [ -d "$_DATA/pages/${PATH_INFO}" -o -d "$_EXEC/pages/${PATH_INFO}" ]; then - REDIRECT "${_BASE}${PATH_INFO}/" - elif [ "${PATH_INFO%\[*\]}" = "${PATH_INFO}" ]; then - theme_error 404 - return 0 fi ;; esac diff --git a/handlers/30_edit.sh b/handlers/30_edit.sh index 315b5c9..6d4e1ea 100755 --- a/handlers/30_edit.sh +++ b/handlers/30_edit.sh @@ -16,13 +16,22 @@ wiki_text() { fi } +case $PATH_INFO in + */\[edit\]) : ;; + *) return 1 ;; +esac + edit_page="${PATH_INFO%\[edit\]}" edit_file="$_DATA/pages/$edit_page/#page.md" [ "$REQUEST_METHOD" = POST ] && edit_action="$(POST action)" -if [ "$edit_page" = "$PATH_INFO" ]; then - unset edit_page edit_action edit_file - # END EDIT SCRIPT, continue in index.cgi +if ! acl_write "$edit_page"; then + theme_error 403 + return 0 + +elif [ "$edit_action" = cancel ]; then + S_RELEASE "$edit_file" + REDIRECT "${_BASE}${PATH_INFO%\[edit\]}" elif [ "$edit_action" = update ]; then if mkdir -p -- "${edit_file%/#page.md}" \ @@ -42,15 +51,7 @@ elif [ "$edit_action" = update ]; then -- "pages/$edit_page/#page.md" fi 1>&2 - REDIRECT "${_BASE}${PATH_INFO%\[edit\]}" - -elif [ "$edit_action" = cancel ]; then - S_RELEASE "$edit_file" - REDIRECT "${_BASE}${PATH_INFO%\[edit\]}" - -elif ! acl_write "$edit_page"; then - theme_error 403 - return 0 + REDIRECT "${_BASE}${edit_page}" elif mkdir -p -- "${edit_file%/#page.md}" \ && S_LOCK "$edit_file"; then diff --git a/handlers/90_brackets.sh b/handlers/90_brackets.sh index f509294..dadd644 100755 --- a/handlers/90_brackets.sh +++ b/handlers/90_brackets.sh @@ -1,10 +1,12 @@ #!/bin/sh -# spacial case for bracket pages that are not handled otherwise +# special case for odd pages that are not handled otherwise +# usually those pages look like handlers (i.e. containing brackets) +# but are not # attachment and edit (and really all) handlers should take precedence case "${PATH_INFO}" in - */\[*\]/*) + */) if [ ! "$(mdfile "${PATH_INFO}")" ]; then theme_error 404 elif ! acl_read "${PATH_INFO}"; then @@ -14,6 +16,11 @@ case "${PATH_INFO}" in fi return 0 ;; + *) + if [ -d "$_DATA/pages${PATH_INFO}/" -o -d "$_EXEC/pages${PATH_INFO}/" ]; then + REDIRECT "${_BASE}${PATH_INFO}/" + fi + ;; esac return 1 -- 2.39.2