Javascript secure proxy

15 September 2023

Implementing a secure proxy for your https certificate-less backend

We all get to a point sometime in our software developer career, where we end up with a backend API that is running on some random test server. In most cases these APIs were made available to us with no SSL security certificates for the host. In another example, we integrate to an API that we do not have control over, with a supplied https url with again no valid certificate.

Typically, when testing out of the dev environment, it is not a problem. Some warnings here and there that you can probably ignore (if you are really, really sure).

One of the issues that arrise, is when you deploy a frontend to a valid hosting service (Firebase, AWS, Heroku etc.) for testing, but the frontend still connects to your unsecure backend API. Most browsers, and mobile OSs will block traffic to these APIs and you end up in all kinds difficult issues trying to test.

Should you be in this position where you do not have control to either install your backend API on a secure host/system, or if it is not your API - there is a solution!

Below is a example of setting up a man-in-the-middle SSL secure type API, which will be used to route traffic to and from your unsecured API.

We will use Javascript to create the app, and use Firebase functions to implement this serverless application.

Using Firebase and Javascript to implement a secure proxy:

Follow the steps below to install Firebase and get your proxy up and running!

1 - Install the Firebase CLI, or if already installed make sure it is up to date

2 - Create a new folder for this proxy and change into the directory with below steps:

mkdir secure-proxy cd secure-proxy

3 - Initialise cloud functions, by using the following command:

firebase init functions

Follow the prompts, I have chosen the following:

- New Project

- Functions language: Javascript

- Use ESLint: No

- Install dependancies: Yes

below is a sample output:

Retro mac

You now have a valid functions project setup, now we will create the proxy.

4 - Change into the functions folder:

cd functions

Here you will see the index.js file along with the standard node type setup (node_modules, package.json)

5 - Install needed packages: express, cors, http-proxy-middleware and body-parser

npm install express npm install cors npm install http-proxy-middleware npm install body-parser

Once done, you should have all the dependencies used in the proxy

6 - Edit the index.js file, and paste the following code:

const functions = require("firebase-functions"); const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const bodyParser = require('body-parser'); const app = express(); const PORT = process.env.PORT | 5000; const API_BASE_URL = 'API_BASE_URL'; const cors = require('cors')({origin: true}); app.use(cors); //a comment app.use( '/', createProxyMiddleware({ target: API_BASE_URL, changeOrigin: true, secure: false, // Set to false to allow connections with invalid SSL certificates onProxyReq: (proxyReq, req, res) => { // Add CORS headers to the backend's response if (req.body) { const bodyData = JSON.stringify(req.body); // Update header for the proxy request proxyReq.setHeader('Content-Type', 'application/json'); proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); // Write the body data to the proxy request proxyReq.write(bodyData); } }, onProxyRes: (proxyRes) => { // Add CORS headers to the backend's response proxyRes.headers['Access-Control-Allow-Origin'] = '*'; proxyRes.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'; proxyRes.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'; }, }) ); = functions.https.onRequest(app);

Remember to update the API BASE URL to your actual backend API.

7 - Now we can go ahead and deploy our function to FireBase by executing the following command (please make sure your FireBase project is set to the Blaze or higher payment plan):

firebase deploy --only functions,hosting

Once deployment has complete, you should see the result as per below sample:

Retro mac

And that is it! You now have a secure URL that will route all communications to your normal unsecured API.

Remember to only use this in test cases where security is a non-issue during testing, as all communication between the proxy function and your API is readable and unsecure!

Get in touch!