AWS S3, PHP Security for Shared Servers

The Amazon Web Services Simple Storage Service (AWS S3) agreement makes it clear that you the user are completely liable for any unauthorized use of your secret key. However, their PHP, Python, and Ruby code examples usually start off with “$secretKey = <insert your key here>” followed by a caution to “only use this example code on a secure server.”

I want to host a PHP application on a shared, remote server where I have only ftp access. I have to assume such a server is not secure, since any sysadmin at the hosting service can browse at will. I’m surely not the first person to host an S3 application on a remote server, yet there are only unanswered threads in the AWS forums regarding best security practices. So I’m guessing that some users are uploading the AWS secret keys and hoping for the best.

Here are the ways I’ve considered for using S3 from a Shared, Remote Web server:

  1. Upload Secret Key – either in plain text or nominally concealed by an XOR hash or hex encoding. It would be concealment only, not encryption, since PHP is not compiled.
  2. Encrypt and Upload – use another language (Java) or extension (Zend engine) that provides some security. AWS has some sample Java code that does this.
  3. Use Public Buckets – from a secure machine, create a public_read_write bucket on S3. The PHP application on the shared server can then use anonymous access to read and write objects without requiring the secret key.
  4. User Grantee – the AWS documentation states that access can be granted to anyone who has an account on amazon.com, even those without an AWS account. Obviously, such a person would not have a secret key. So the shared server application could use an amazon account to access a bucket with such a grant. However, the documentation does not explain how to sign a request with a canonical account name without a secret key.

I rejected options 2 & 4 as having too many unknowns at this stage of development. Adding a new language just to encrypt a key is a big hit in complexity. Similarly, with no cookbook example and the rather hastily assembled user documentation, I expect lots of trial and error for option 4. But once documented, option 4 would be my clear first choice.

Options 1 & 3 shift risk between a particular bucket and one’s secret key. With option 3, anyone who discovers the publicly read/writable bucket can use it immediately without even needing to find my PHP source code. But since they don’t have my secret key, I still have control over the bucket and can turn it off (delete it or make it private).

Option 1 exposes no public buckets on the web. But the worst case (someone gaining access to the remote server and stealing the secret key) has a big exposure. Only Amazon customer service can turn off a secret key, and they’re available only by email and only during business hours. If they take a week to shut off the key, I’d be liable for all of the charges.

My choice is option 3. I’m more comfortable with the risk profile being concentrated onto one bucket. Also, option 4 is a straighforward upgrade once more documentation becomes available. One unknown: is there any easy way for hackers to scan AWS S3 searching for public buckets? Let’s hope not.

posted in php, s3 by Bozzie

1 Comment to "AWS S3, PHP Security for Shared Servers"

  1. Martijn wrote:

    Interesting post. I was wondering about the same issue and you’ve listed the choices quite clearly.

Powered by Wordpress and MySQL. Theme by openark.org