Create and secure your own proxy with cURL and MCrypt

JavaScript’s same-origin policy can be a pain. Of course it’s very necessary for security reasons, but sometimes you want to access a remote web service client-side, or manipulate the display of remote content in an iframe. There’s a still a way to do these things of course, and it’s to build a server-side interface for the remote site and attach your JavaScript to that. Building a generic proxy-style interface is tempting, but can be dangerous if it’s not properly secured. Luckily, securing such a system is possible and relatively simple.

What this will do

The goal here is to built a single PHP service that accepts a single GET variable representing a URL, makes a request to that URL, and returns the response. This can be implemented in its simplest (and most vulnerable) form with a few lines like the following:

If you load up this page with “http://www.xkcd.com” set as the “url” GET parameter, you’re browser will receive the HTML of xkcd.com as the response. This accomplishes the goal as stated above, but has one major problem: anyone who knows about the existence of this page can use it to send whatever they want through your server. This can lead to drain on your server, and worse you can end up giving aid and comfort to spammers and attack pages.

In order to prevent this, but still leave the flexibility to use one page for dynamic remote requests, I decided to create a system that sends an encrypted URL to the server, which decrypts it and makes the request. Without knowing the encryption key any malicious attacker would be unable to direct your server to their content.

Make it secure

In order to accomplish this encryption securely, it must be done manually and in advance as opposed to dynamic usage client side. If JavaScript were able to perform the encryption, then any attacker would be able to find the encryption key and use it to encrypt their own information.

Since the client side is staying completely removed from the encryption equation here, I decided to use symmetrical encryption instead of asymmetrical for ease of use and because the benefits of asymmetrical encryption wouldn’t make a difference in this context. Essentially a URL will be encrypted using a passkey, then the encrypted URL will be sent to the server which will use the same passkey to decrypt the URL.

Encryption method

PHP’s MCrypt extension is a fairly standard-usage item, and provides powerful symmetrical encryption that is well suited to this project. The usage for encryption and decryption is straightforward, just provide the passkey and data to encrypt/decrypt, and choose the encryption algorithm you want to use. For this project I used the Rijndael cipher which is at the heart of the Advanced Encryption Standard.

To add security, I also run any passkey used in this project through the sha256 hashing algorithm to ensure that the passkey will always have the maximum size of 256 bits allowed by Rijndael. In PHP this is done by calling the hash() function and passing it ‘sha256’ as the algorithm. I also had to set its optional third parameter to TRUE so that it would return the raw hash (31 characters) as opposed to the hex representation (64 characters) so it would be usable by Rijndael.

The end result, if both the passkey and data to encrypt are passed as GET parameters, looks something like this for encryption:

And this for decryption:

Calling rawurlencode() on the encrypted text is important because it’s going to be almost entirely special characters which will not play nice in a URL otherwise.

Try it

I’ve created a couple of small services to let you test out the code demonstrated above. Just fill out the data you want to encrypt and the passkey to use, and the server will return your data fully encrypted, both raw and in a URL encoded format. Then pass the encrypted and encoded data with the same passkey to the next function, and it will be decrypted back to your original text.

Encrypt!

Passkey:
Data to encrypt:
Result:

Decrypt!

Passkey:
Data to decrypt:
 
Result:

Bonus feature

If you want to use this to embed remote content as an iframe you can manipulate with JavaScript, I’ve built another feature that makes it all run a bit more smoothly. Trying to load content from a different domain on your own domain will break any relative URLs, including CSS files, scripts, and images. To combat this, I use PHPs DOMDocument model to insert a <base> tag at the top of the <head> that set’s the document’s root to be that of the original site. This should restore all of the images, scripts, and styles broken because of relative links.

Tagged with: , ,
Posted in HTML & CSS, PHP, Server Administration, Server Side Code, Try It
2 comments on “Create and secure your own proxy with cURL and MCrypt
  1. Damien says:

    Od nastepnego tygodnia rozpoczynam odchudzanie, kto sie odchudza ze mna?
    Wyszperalam w google dobry plan na schudniecie, wygoglujcie sobie – Jak szybko schudnąć Kamidoni zaleca

  2. Clara says:

    If you are interested in topic: earn online money free club flyers – you should
    read about Bucksflooder first

Leave a Reply

Your email address will not be published. Required fields are marked *

*