Prevent access through ip address - node.js

Using express.js how do I prevent requests from accessing my server through the ip address instead of through the domain fronted by cloudflare?
This is to prevent googlebot from indexing http://xx.xx.xx.xxx/

This is what I ended up with, hope it works.
app.get('/*', function(req, res, next) {
if (req.host === '129.8d.xx.xxx') {
res.redirect(301, 'https://example.com' + req.path)
}
else {
next();
}
})

Related

Why does HTTP -> HTTPS redirect fail in nodejs when no subdomain is specified?

I'm running a nodejs webapp on Heroku and I want to redirect all users that access via http to https with the corresponding URL.
I have it mostly working however the user is redirected to the home page if no subdomain is specified. Any idea what is going on here?
The node rerouting middleware:
app.enable('trust proxy');
app.use((req, res, next) => {
if (req.get('X-Forwarded-Proto') !== 'https') {
res.redirect(`https://${req.headers.host + req.url}`);
} else {
next();
}
});
Works:
http://www.example.com/page redirects to https://www.example.com/page
Fails:
http://example.com/page redirects to https://www.example.com
Because req.url is an inherited property from Node.JS's http module and does not necessarily contain the original URL. Express.JS documentation also states it, https://expressjs.com/en/api.html#req.originalUrl
If you want to retain the original url you should use the correct property, which is originalUrl.
app.enable('trust proxy');
app.use((req, res, next) => {
if (req.get('X-Forwarded-Proto') !== 'https') {
res.redirect(`https://${req.headers.host + req.originalUrl}`);
} else {
next();
}
});

How to work with wilcard subdomains on localhost in a node js application

I am having a application that runs as something.localhost (*.localhost) depending upon the subdomain name action needs to get identified.
You can use req.headers.host to get host identified.
app.get('*', (req, res, next) => {
if(req.headers.host == 'something.localhost') {
//your code here
}
});

Node.js non www to www redirect does not working

I have referred to this:
https://www.hacksparrow.com/how-to-forward-non-www-to-www-domain-name-and-vice-versa-in-node-js-express.html
And to other Stackoverflow questions, but I still get errors when doing what they said:
This code:
app.get('/*', function(req, res, next) {
if (req.headers.host.match(/^www/) == null ) res.redirect('http://www.' + req.headers.host + req.url, 301);
else next();
});
Redirects me to www.localhost:8080 ...
I have tried other syntax but still not working:
app.get('/*', function(req, res, next) {
if (req.headers.host.match(/^www/) == null ) res.redirect('http://www.ride4you.co.il', 301);
else next();
});
(It redirects too many time until Chrome is timedout).
My question is how to fix this, in order to redirect ANY kind of addresses in the web address bar to https://www.mydomain.co.il,
for example: mydomain.com www.mydomain.co.il http://mydomain.co.il, I want all of them to point to the first I wrote.
Thanks.
Only allow the specific host you want through, and catch the unlikely case that it's a HTTP/1.0 without a host header.
app.use((req, res, next) => {
if ( !req.headers.host || req.headers.host === 'www.mydomain.co.il' ) return next()
res.redirect('http://www.mydomain.co.il/', 301)
})
You can keep the users original request path in the new URL.
res.redirect('http://www.mydomain.co.il'+req.originalUrl, 301)

Forwarding http to https in node.js express app using EBS & ELB environment

I am using the following to redirect all http requests to https requests.
I can see from logs that the header 'x-forwarded-proto' is never populated and is undefined.
app.get('*', function(req, res, next) {
//http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-proto
if (req.headers['x-forwarded-proto'] != "https") {
res.redirect('https://' + req.get('host') + req.url);
} else {
next();
}
});
It is causing a redirect loop. How can I redirect properly without looping?
edit:
my original answer below is for express 3.x, for 4.x you can get a string http or https in req.protocol, thx #BrandonClark
use req.get, not req.headers. Note that POST requests and all other non-GET will not see this middleware.
It's also possible that Express does not carry the x-forwarded-proto header across when you redirect. You may need to set it yourself.
app.get('*', function(req, res, next) {
//http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-proto
if (req.get('x-forwarded-proto') != "https") {
res.set('x-forwarded-proto', 'https');
res.redirect('https://' + req.get('host') + req.url);
} else {
next();
}
});
Another way to force https:
function ensureSecure(req, res, next){
if(req.secure){
// OK, continue
return next();
};
res.redirect('https://'+req.host+req.url); // handle port numbers if non 443
};
app.all('*', ensureSecure);
You can edit the nginx config file in the EC2 instance. SSH to ec2 instance and follow the following steps
go to /etc/nginx/conf.d
open 00_elastic_beanstalk_proxy.conf
sudo vi 00_elastic_beanstalk_proxy.conf
put
location / {
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
…
}
reload nginx
sudo /usr/sbin/nginx -s reload

node.js expressjs pattern match not equal

I'm using expressjs with node and running both https and http.
I want to require that all routes for /secure/* use https. This is done:
app.all("/secure/*", function(req, res, next) {
if (!req.connection.encrypted) {
res.redirect("https://" + req.headers["host"].replace(new RegExp(config.http_port, "g"), config.https_port) + req.url);
} else {
return next();
};
});
However, I also want to require that all routes that are not using /secure/* and try to access https, are redirected using the same method to http.
I tried doing this:
app.all("*", function(req, res, next) {
console.log(req);
if (req.connection.encrypted) {
res.redirect("http://" + req.headers["host"].replace(new RegExp(config.https_port, "g"), config.http_port) + req.url);
} else {
return next();
};
});
But I end up in a redirect loop when accessing the https pages. Is there a way to specify all routes, except those with /secure/* ?
Thank you!
A simple solution to your problem is:
app.all("*", function(req, res, next) {
if (req.connection.encrypted && !/^\/secure/.test(req.url)) {
res.redirect("http://" + req.headers["host"].replace(new RegExp(config.https_port, "g"), config.http_port) + req.url);
} else {
return next();
};
});
Only do the redirect if the URL doesn't start with /secure.
However, I'd propose that instead of the redundant 'secure' label in the URLs, just mark certain paths as requireHTTP or requireHTTPS. You know you can pass multiple methods into app.get and other such router methods, right? Assuming you define requireHTTP and requireHTTPS (which would be identical to your original functions), you'd just do:
app.get("/path/to/keep/encrypted", requireHTTPS, function(req, res) {
// Rest of controller
});
app.get("/path/to/keep/public", requireHTTP, function(req, res) {
// Rest of controller
});
app.get("/path/you/dont/care/about/encryption/status", function(req, res) {
// Rest of controller
});
That should do it.

Resources