modified: Monday 6 May 2019
author: Hales
markup: textile
Software release: Minisleep
First: have a read of the release page in question.
I thought it would be easy to release. It took me 2.5 days of solid work just to write the documentation for. Initially I started writing a really in-depth tutorial, but I soon discovered that making a foolproof guide on how to setup a webapp on any webserver is an infinite problem. I ended up settling with some provided (working out of the box) example configs and some vaguer installation instructions.
I’d really appreciate feedback on how I’ve approached the security problem. I think it’s the most sane option, but I could be wrong.
Minisleep has diverged quite a bit from this website (Darksleep), but mainly in terms of fixes. I want to merge all of that back into here, but it’s going to take some effort.
One highlight from the code:
#!/bin/sh
# minisleep_lessgreedy.cgi: a shim to make minisleep.cgi work with certain HTTP
# webservers that are very particular about CGI script read()s.
# There are many different HTTP servers out there that support CGI and they all
# have slight differences in how they do it. One particularly problematic area
# is how they provide stdin (body content, eg POSTs) to your CGI scripts.
#
# --- Category 1: Sensible & forgiving ---
#
# Examples: apache, lighttpd
#
# - If you read too little stdin: no one minds
# - If you read too much stdin: your reads return nothing or fail, no one minds.
#
# --- Category 2: Pushy ---
#
# Examples: (Can't recall the name, encountered once on a shared host)
#
# - If you read too little stdin: the user is redirected to an error page.
#
# This is annoying, but I can maybe understand it. If all of stdin has not
# been read then perhaps your script crashed early.
#
# --- Category 3: Confused ---
#
# Examples: hiawatha, yaws
#
# - If you read too much stdin: your read calls hang forever.
#
# This doesn't make sense to me. Why hang the read? You know you have nothing
# more to provide, making the script hang forever seems impolite. Worst of all
# you then kill the script for taking too long >:|
#
# In practice this leads to a couple problems:
#
# (1) Script authors can't use simple methods for storing POST'd content, eg:
#
# cat > posteddata
#
# (2) Students & learners have harsh difficulty working out what is going on
# when their scripts only hang with certain HTTP webservers and under certain
# conditions. If they are not aware of what read calls or sockets are then
# they're SOL to identify and fix this problem.
#
# I'm really concerned about the student side of things. I try to encourage the
# use of CGI as much as I can with students, because I see many of them get very
# confused with the abstractions many frameworks provide:
#
# https://lobste.rs/s/pdynxz/long_death_cgi_pm#c_lw4zci
#
# TL;DR: I've had students think templates are things sent to the web browser,
# and I typically find that teaching how HTTP works can be really beneficial.
#
# Anyway, enough of that.
# Solution: read exactly the number of bytes (not one more or one less) that we
# are told we can; and pipe it to minisleep.cgi in a way that lets excess read
# requests fail harmlessly. This keeps boths sides happy.
# Find where this script (and therefore the website) is located
cd "$(dirname "$(readlink -f "$0")")"
if [ -z "$CONTENT_LENGTH" ]
then
echo '' | ./minisleep.cgi
else
head --bytes "$CONTENT_LENGTH" | ./minisleep.cgi
fi
For now I’m going to get some sleep of my own.