I'm writing an Express application that creates and exports a document based on the selections a user makes from two dropdowns. The dropdown values are passed as route parameters after a button is pressed, then necessary functions are called within the route method to create the document and send it back to the user.
How can I prevent a user (if possible) from calling/accessing this route by manually inputting route parameters into the URL bar? They should only be able to access the route from the button press.
Below is some general code for the functionality of my application...
Code for grabbing/sending values after button click:
export.onclick = function() {
let index1 = dropdown1.value;
let index2 = dropdown2.value;
fetch('/' index1 '/' index2)
// Convert response to blob object for download
}
Route Code:
app.get('/:index1/:index2', function (req, res) {
// Call functions to create document
// Return document back to user
});
The dropdowns are dynamically populated using data obtained from the response of an API. The value of each dropdown option represents the index of that option. The user being able to input random indices allows for invalid input; however, there are not necessarily boundaries to the inputs as the dropdowns are dynamically populated based on various user restrictions. For this reason, preventing the user from being able to access the route by inputting parameters in my mind would be ideal.
CodePudding user response:
You can't take away the ability to enter an URL into the browsers address bar but you can decide to just not handle the resulting GET
request in your backend. Instead you can listen for a POST
request.
app.post('/:index1/:index2', function (req, res) {
// Call functions to create document
// Return document back to user
});
export.onclick = async function() {
let index1 = dropdown1.value;
let index2 = dropdown2.value;
const response = await fetch(`/${index1}/${index2}`, {
method : 'POST'
});
}
This is by no means a security feature, the user would still be able to create a POST
request manually if she knows what she's doing and/or using a request client like POSTMAN or similar.
But why ?
It seems to me this could be a XY Problem. Why do you want to prevent the user to manually type in an URL into his address bar ? Could it harm your server/business in any way ? If yes, then you have a different, bigger problem at hand.
CodePudding user response:
add a token to protect your get request on the server side
like this
app.get('/:index1/:index2', function (req, res) {
if (req.query.token !== 'foo') {
// invalid the request
}
// Call functions to create document
// Return document back to user
});
to send request to the url you will need the token
/:index1/:index2?token=foo
or just add the token on the request header
Then the following question could be
Do i need a dynamic token to secure the /:index1/:index2
API?
if no, then the user still can type the URL with this fixed token
if yes, you will need another API to generate the token on the "button page"
fetch('/get_new_token')
// get the token via this API
const token = ...
export.onclick = function() {
let index1 = dropdown1.value;
let index2 = dropdown2.value;
fetch('/' index1 '/' index2 '?token=' token)
// Convert response to blob object for download
}
you can use a key to encrypt your token
or add a signature into your token for verifying the token did not modified
and if you want your token will expire after a timestamp
add a timestamp info into the token
then verify the timestamp on the service side