That was my thought too at one point. But then I set that 15 second alarm clock for the whole script. In Google Chrome you can see the % uploaded while it sends the file to the server; immediately after it got to 100% I got my error message about the timeout expiring. So it looked like Apache started my CGI script earlier and it waited for a while (perhaps when the CGI object is created it blocks until Apache receives the whole request?)
Setting an upload hook is how you can create a progress bar for file uploads; in this case the CGI script is running since the beginning of the request. Although in my experience if the upload hook crashes (intentionally or due to run-time error) it doesn't affect the rest of the script.
Anyway, I looked into that Apache config instead. I put a limit of 5 MB for the directory that contains this (and other) CGI scripts - none of the other CGI scripts accept inputs greater than 5 MB (in fact none of them accept higher than 1 MB but I'm adding some wiggle room). Tried uploading VirtualBox again instead of a font file, and after 5 MB was uploaded Apache reset my connection. :)