?

Log in

No account? Create an account
entries friends calendar profile my webpage Previous Previous Next Next
Pictures and geekiness... - Tina Marie's Ramblings
Red hair and black leather, my favorite colour scheme...
skywhisperer
skywhisperer
Pictures and geekiness...
I've been unhappy with my website photo gallery for a long time. It's ancient, written in perl, difficult to maintain, it uses the file system for organization, and keeping thumbnails with their pictures is impossible. Everything has to be updated with FTP, then there's a shell script that has to be run. There was no real support for attaching text to a picture, although I did have a hack that let you put a title on a directory.

So I've been re-writing it the last month or so. The new version is all PHP, and stores the pictures in mySQL. It stores the full-sized picture in the database, and generates and caches all other sizes on the fly. It's got a real permission system, where photos and tags can be restricted to certain groups of users. It uses a tagging system similar to LJ, so pictures can be in multiple categories at the same time. Pictures get uploaded from a web page, with real title and description fields.

Version 2.0 is scheduled to have a Windows uploader and real galleries, but that's going to be a few months out.

If you're one of the people who gets server space from me, and you want this set up in your space, or if you don't get server space from me and want to use it anyway, drop me an email.

Tonight I sat down and put pictures in it from a trip to Moody Gardens last month. You can see the whole set here. You don't have to log in to see them, but if you want to create a user, go for it.

I'm getting quite fond of PHP. This was my first really big project, and I think it turned out well. I run PHP 5, so I have real classes, and that helps a lot. My next project: A PHP-based event calender for my new WoW guild. After that, I'll be ready to start on version 2 of the photo gallery....

Tags: ,
Current Mood: accomplished accomplished

15 comments or Leave a comment
Comments
alioth1 From: alioth1 Date: September 3rd, 2006 11:19 am (UTC) (Link)
What's wrong with Perl? You wrote that there as if it was a bad point :-)

Watch out with PHP - it's terribly easy to write insecure code so much so I nicknamed PHP the antithesis of PGP (which stands for Pretty Good Privacy). I call PHP 'Pretty Hopeless Privacy'.

Well, PHP has improved quite a bit, but it still very easy to shoot yourself in the foot.

Also, having written quite a bit of PHP in the past, it's a really bad idea to mix PHP with HTML (which is how it's normally written). I prefer to have the PHP load the HTML from various templates, and fill in the blanks - so when you change your web design you just need to change the template and any associated CSS.

But having done both PHP and Perl, I still generally prefer Perl for most projects (especially anything to do with a database). Perl's DBI is much nicer and allows you to switch backing database a bit easier.
(Deleted comment)
alioth1 From: alioth1 Date: September 3rd, 2006 07:08 pm (UTC) (Link)

Re: PHP and security

The main reasons (I don't know about PHP5, I've not done much with PHP5 yet, but these are certainly issues in PHP4)

- No taint mode: means if you accidentally forget to check an input, you won't know about it until you're pwned
- No strict mode: a typo in a variable name can have unintended consequences (potentially exploitable bugs)
- by default, a lot of dangerous things are enabled, although register_globals is off by default now, there were in PHP4 quite a lot of things enabled such as being able to include arbitrary PHP files from remote servers. Combined with an attack that exploits unchecked input on a script which the programmer hasn't caught (particularly in a complex PHP program) this can be quite nasty and is a common way of getting pwned.

#!/usr/bin/perl -Tw has prevented so many exploits before they were even known about. I'm much happier about the default security of, say, Bugzilla than any PHP program of equivalent complexity.

Other things I don't like about PHP are things like the mysql_ functions that should never have been put in the language in the first place - these should have been abstracted behind something like DBI from the git go (and should be deprecated by now, but aren't). It's made an awful lot of code much more painful than necessary to port to a different DB engine.
(Deleted comment)
skywhisperer From: skywhisperer Date: September 3rd, 2006 09:52 pm (UTC) (Link)
My first pass has PHP writing the HTML. But I'm seriously considering switching to Smarty as a template engine.
(Deleted comment)
alioth1 From: alioth1 Date: September 3rd, 2006 07:09 pm (UTC) (Link)

Re: Curiosity

I would guess it's to avoid having an images directory with filemode 777 (which you'd have to have, unless you run PHP as a cgi-script or fastcgi with mod_suexec).
(Deleted comment)
skywhisperer From: skywhisperer Date: September 3rd, 2006 09:08 pm (UTC) (Link)

Re: Curiosity

Which is, in my opinion, just as bad. I don't let apache write anywhere it doesn't absolutely have to, and never, ever under any of the various webroots.

I don't want there to be any way a user could upload a file into a place where it was then executable.
(Deleted comment)
skywhisperer From: skywhisperer Date: September 3rd, 2006 09:50 pm (UTC) (Link)

Re: Curiosity

That's active security. I think that's fine, but it's easy to forget in just one place. And it only takes one place to have a problem.

Having a system policy that says "apache cannot have write access at all under webroots" is passive security - it works whether you remember or not.

Both is best. :)
alioth1 From: alioth1 Date: September 4th, 2006 07:53 am (UTC) (Link)

Re: Curiosity

Which - considering your httpd is open to all and sundry on the Internet - is tantamount to the same thing. Even chmodding -x any uploaded files, or mounting the writeable area noexec, this still isn't safe (in terms of someone uploading and executing an exploit) - because you can still execute shell scripts with "sh somescript.sh", even if somescript.sh has filemode 644 or is on a noexec filesystem. That's all an attacker needs to do to then download their spamming script to the same world writeable directory.

The only way you can really secure a writeable location like that is all of the following:
- implement strong egress filtering on the machine, so scripts can't make outgoing connections to random internet addresses.
- create an SElinux policy so that only apache can read and write to this directory via a designated script (only practical with CGI, because otherwise you have to assign the SElinux policy to httpd and then you're back to square one - if you can assign it to a CGI script, you can give the CGI script very limited privileges via SElinux)
- make sure that tools such as wget, compilers etc. cannot be run by user 'httpd'.

But doing all those things is a lot more complicated - and there's a lot more to miss - than just shoving the images in the database.

In any case you've got to make sure there's no way your script can write to /tmp or /var/tmp, because that's another favorite trick of the crackers - put your bad script in there.
skywhisperer From: skywhisperer Date: September 4th, 2006 04:13 pm (UTC) (Link)

Re: Curiosity

I don't let apache write to /tmp, but if it's not under a webroot, how can you run it?

What there needs to be is some way to flag a directory so that no matter what, no one can ever execute a file from it.

alioth1 From: alioth1 Date: September 4th, 2006 05:23 pm (UTC) (Link)

Re: Curiosity

There isn't really a way (well, not with standard Unix permissions). As far as the kernel is concerned, doing "/bin/sh /tmp/foo.sh" isn't actually executing foo.sh - it's running /bin/sh with the argument /tmp/foo.sh. You can mount filesystems noexec - it prevents something like '/tmp/foo.sh' or '/tmp/someotherexecutable' but not '/bin/sh /tmp/foo.sh' or even 'php /tmp/bar.php'. Or 'sh ../../../../var/tmp/wibble.sh'.

There are ways to protect writeable directories, but you need to use an SElinux policy (chances are, in RHEL4, a process started from Apache can't read/write /tmp or any other globally writeable directory due to the SElinux targeted policy). Certainly, by default, Apache can't read/write anywhere in /home on RHEL4 if you use the RH targeted SElinux policy even if the directory is chmod 777. IIRC, the RedHat targeted policy for Apache stops it from reading/writing anywhere outside of the web root. A reasonably secure way of allowing Apache to write to a location with this policy is to place the writeable directory somewhere outside of the web root (so Apache can't read or write it), and write a CGI script (in PHP or Perl or C or whatever language you want) and give the CGI script appropriate ACLs and write a policy for the script so it can read/write the directory. That way you contain any exposure to that particular CGI script and that script only. Securing one script is a lot easier than having to go through and secure anything that might possibly try and write somewhere.
skywhisperer From: skywhisperer Date: September 3rd, 2006 09:06 pm (UTC) (Link)

Re: Curiosity

Yes. And I got bitten, years ago, by a system we devised at work where data was stored spread out among multiple files. I don't want 5 files all representing the same picture - then it becomes a nightmare to maintain. My old code did that, and it didn't work well at all.

So now, I have one table where one row is a picture, and it contains things like the title and description and filetype and so on. Then another table that has the data, both the original and the caches of the smaller sizes, all tied together with a common ID.
15 comments or Leave a comment