laren0815 laren0815 - 3 days ago 4
Javascript Question

How can I make a Nodejs express.js (proxy) server available only for a specific domain?

I have developed a small images proxy in node.js (expressjs). This proxy should reduce all images, which come from my website "www.myUrl.com". This also works well so far. But I would like to protect the proxy against unauthorized access.
That is, as soon as an image is loaded via the proxy from another url, an error message "unauthorized" or null ... is to be returned.
I have already tried to read the header "origin" via

req.headers.origin
, but this was empty:

console.log(JSON.stringify(req.headers))
shows this:

{
"host":"myImageProxyUrl.com",
"user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/54.0.2840.100Safari/537.36","accept":"image/webp,image/*, */*; q=0.8",
"accept-encoding":"gzip, deflate, sdch, br",
"accept-language":"de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4",
"connection":"keep-alive",
"referer":"https://myUrl.de/myPage",
"x-forwarded-for":"ip1,ip2",
"x-forwarded-proto":"https, https",
"x-mod-original-region":"joyent-eu-ams-1.onmodulus.net",
"x-mod-region":"aws-us-east-1a.onmodulus.net"
}


The proxy is hosted at modulus.io. "www.myUrl.com" is a Meteor.js app.

How can I make the proxy available only for the domain "www.myUrl.com"?

Thanks.

Update:

Images are simply loaded over an image tag in the client:

<img src='http://myImageProxyUrl.com/imageXY.png' />

rsp rsp
Answer

If I understand your question correctly (it is not very clear) then you want to disallow hot-linking of the images served by your proxy on other websites than your own. If so then you need to check the Referer header. If you have a route like this in your Express app:

app.get('/something', function (req, res, next) {
    // some response
});

then you can change it to:

app.get('/something', function (req, res, next) {
  if ( checkReferer(req) ) {
    // respond normally
  } else {
    // respond with error
  }
});

Implementing checkReferer can be something like:

function checkReferer(req) {
  var url = 'http://good.url.com/';
  return req.get('Referer').indexOf(url) === 0;
}

Or, if you want to allow uses with no Referer header:

function checkReferer(req) {
  var url = 'http://good.url.com/';
  return !req.get('Referer') || req.get('Referer').indexOf(url) === 0;
}

The above will work if there is no Referer header at all but if there is then it must start with the right URL. This function may need to get more complicated if you want to add more domains, or if you want to allow both example.com and www.example.com etc. What's important is that this function should return true if the Referer is ok for your requirements and false if it's not.

A better way (thanks to xShirase for pointing it out in the comments) would be to add a middleware instead of modifying the route handlers. That way you don't have to duplicate that logic in many places. For example:

app.use(function (req, res, next) {
  if ( checkReferer(req) )
    return next();
  res.status(403).send('Forbidden');
});

(the checkReferer is the same as above) and then the route handlers with no changes:

app.get('/something', function (req, res, next) {
    // some response
});

app.get('/something/else', function (req, res, next) {
    // another response
});
Comments