Express app.get static file with "." in filename - javascript

app.get('/images/:filename', (req, res, next) => {
console.log(req.params.filename);
const newUrl = `/static/images/${req.params.filename}`;
req.url = newUrl;
next();
});
Above code works fine if filename does not contain a special character .
For example localhost/images/myImage.jpg will print out myImage.jpg.
If filename contains a . such as localhost/images/my.Image.jpg, console will not print out anything. Is there a way to fix this?
Edit: Added code below. I'm not sure what it does.
app.get(
/^.+\.(jpg|jpeg|gif|png|bmp|ico)$/,
(req, res) => {
res.status(404).end();
}
);
Edit 2: My bad! Like someone's comment, I found the problem was actually from Service Worker. It was apparently messing with caching.
Could somebody explain what ^.+\.$ does in the second piece of code above? I'll mark the answer for that one instead.

I assume it's express.js? If so, :parms is not the best candidate to pass complex values (e.g. something more complex that simple alphaliteral, ehm, params). You could try to pass it to req.query isntead of params and properly escape it client-side and unescape server-side

Please refer to this documentation:
Serving static files in Express

Related

how can i make url shortener api in express.js?

I'm doing a link shortener. The link shortener works very well but now I'm trying to do API for it. The problem is that if I pass the URL argument in the get URL it's not working. I tried a lot of things but it's not working. When I do like http://localhost:3500/api/create/google.com it works but when I do http://localhost:3500/api/create/https://google.com it's not working because of the https://. These are the last 3 inputs via my API that failed: http://https:google.com, google.com, http://
I'm using express and mongoose. Here's my code:
app.get('/api/create/:shortUrl(*)', async (req, res, next) => {
if (req.params.shortUrl.includes("https://") || req.params.shortUrl.includes("http://") || req.params.shortUrl.includes("/")) {
req.params.shortUrl = req.params.shortUrl.replace("https://", "").replace("http://", "").replace("/", "")
}
if (req.params.shortUrl == "") {
res.send("invalid URL")
}
await shorturl.create({full: `http://${req.params.shortUrl}`})
const shortUrls = await shorturl.find().sort({_id: -1}).limit(-1)
const latest = shortUrls[0]
res.send("https://p33t.link/" + latest.short)
});
You have to properly encode portions of the URL that contain restricted characters such as : and // that aren't part of the actual protocol to make it a legal URL. So, the idea is that you encode the "parameter" before appending it to the URL. Presumably, you would use encodeURIComponent(), depending upon exactly where you're placing it in the URL.
After parsing the core part of the URL, a web server will decode the remaining components of the URL and give you back the original characters. I would suggest that your particular use would probably work better as a query parameter rather than a part of the path which would give you this when properly encoded:
http://localhost:3500/api/create?u=https%3A%2F%2Fgoogle.com
And, you could then use:
app.get('/api/create', (req, res) => {
console.log(req.query.u);
...
});

How to deal with Path Traversal?

I'm trying to understand how to deal(in a secure way) with Path Traversal.
For example an application receives from a client a file name via REST API in JSON, look for it in the non-accessible(by outside) directory and retrieve a response with the file:
app.get('/', (req, res) => {
const fileName = req.body.fileName;
// some code...
fs.stat(`./nonAccessibleDir/${fileName}`, async function(err, stat) {
// some code...
});
// some code...
}
The problem with the above approach is that a client can send something like "../" in the fileName request and it will "eat" it without an issue. How can one deal with this kind of scenarios, what and how I should fix this vulnerability, please?
Update:
Sorry, but I forgot to mention that I know I should check the input I receive, but what if I need to pass the "/" and "." in the input? Also, if I don't need this characters, is that all I need to check to remove the Path Traversal vulnerability?
An easy way would be to validate the fileName through a regex that detects any ../ segments and returns an error if any are present.
if (fileName.match(/\.\.\//g) !== null) {
// return an api error
}
You could have quite a tight validation rule that prevents any forward slashes in fileName at all, making it only possible to point to a file directly in your desired directory.

How do I pass a whole URL with http e.g. "http://www.facebook.com" as a parameter to node/express "/:param"?

I can't seem to pass a whole url e.g. "http://example.heroku.com/http://www.facebook.com"
app.get('/:url', function(req, res){
var url = req.params.url;
// do something with url...
}
I always get an error that says "Cannot GET /http://www.facebook.com".
How do I get past this?
Some characters (like /) have special meaning in URLs and need to be encoded.
http://example.heroku.com/http%3A%2F%2Fwww.facebook.com
Most programming languages have a function (possibly via a third party library) which can encode that for you. In JavaScript, for instance, that is encodeURIComponent.
You can use regular expression. For example:
// http://localhost:3000/mountpoint/http://www.facebook.com
app.get( /^\/mountpoint\/(.*)/, function(req, res) {
var url = req.params[0];
res.json(url);
});
Thanks for the comments, answers but I've found out I could use the wildcard and I was able to get the whole URL parameter without running into the 'Cannot GET /' error
'/*'

Node.js: Returning proper JSON from mongoose query

I have this express application with mongoDB as the database and handlebars as my server-side templating engine. I am not using AngularJS or Ajax in my application.
In one of the routes, I have to render the page as well as send over a json file from the database. However, I am not able to achieve this.
Here is code snippet the my route:
router.get('/disks', function(req, res, next) {
places.find({"category": "disks"}, function(err, disks){
if(err){
throw err;
}
res.render('disks',
{
'risime': JSON.stringify(disks)
});
console.log(disks); // PROPERLY LOGS TO THE CONSOLE
});
});
In the hbs, I am trying to capture it, but I don't even think that it is JSON.
Here is how it gets logged in the client side:
[{"_id":"5704630a7d4cd367f8dsdce7","name":"Seagate",:"This awesome Hard disk",","categories":["SDD","256GB"]}]
What is the issue and how do I resolve it?
It's handlebars that "html escapes" your string (which is what you normally want).
if you don't want that, you can use the "triple-stash" notation, like this:
{{{risime}}}
You can read about this here: http://handlebarsjs.com/#html-escaping
I think you need to add this before render:
res.type('application/json');
The client will know this is a JSON, not a HTML or a plain text and it will be shown correctly.
I hope my answer will help you.

Extract URL from a server in Node.js

I'm making a Node.js server and I need to extract one part from a URL with this structure:
https://lets-talk-saku-gie-sakura.c9users.io/sala?extract
I just need the extract part.
I need to use the app.get method. However, the only way that I've found is:
app.get('/sala/:id', function (req, res) {
req.params.id;
});
This doesn't work; do you know how can I extract it?
req.params is for URL parameters like :id. Since you want a query parameter you should use req.query instead.
app.get('/sala/:id', function (req, res) {
console.log(req.query);
});
req.query might seem like a way to do this but, unfortunately, it's only useful when you know or expect certain query strings. Your best bet, I think, is to use req.originalUrl and then use a regular expression to find the part of the url you want to extract. See http://expressjs.com/en/4x/api.html#req.originalUrl
The nodejs HTTP doc has an example that can help you:
var obj = require('url').parse(req.url);
console.log(obj.query); // output: extract

Categories

Resources