Yes, this is evil. Yes, it's gory. I don't have much spare time, and (*blush*) I like to sleep every so often. That's my excuse, anyway.
Anyhow - I think I've handled most of the obvious attacks except the "fill up entire quota with duff images" one, which I don't think I really can deal with without sacrificing some of the Wiki spirit.
The source is available [here]. The two nonstandard modules used are [FileCook] and [SafeIO]. They provide functions for locking, closing files and releasing locks on death, and transparent reading and writing of complex Perl structures to and from filehandles; I imagine there's better ways of doing all of this, but I wanted to see what I could do from scratch. The /CardServer will use them too, and eventually so will the wiki (I intend to refactor IO-related stuff into modules, since all the scripts use the same code; you'll notice the host lookup code is already in [SafeIO]).
To get the script installed, you need to make an empty directory for image data that the script has permission to write to, and then edit the first few lines of the source to tell the script where it is.
Things I still need to do:
would be nice to list Wiki pages that use the image on the "change image" page, along with links.
non-numeric ID support
do something about people who've just uploaded an image hitting "refresh" in their M$ browser, which then happily goes off and submits another copy of the same image
Send a cookie with the 'what do you want to upload' page. Log that cookie when they hit submit. If the submitted cookie matches one in the list, reject the upload with a message saying what you think they did, and asking them to do it again if they really meant it. --Vitenka
Hm. Don't need to use a cookie - I can achieve the same effect by sticking a random number in a hidden field every time I generate an upload form, retrieving the random number when I get handed an image, and comparing it against the last one I got for that image. I'll do that this weekend, I think :) - MoonShadow