So we are designing a public facing Suitelet as an...
# suitescript
m
So we are designing a public facing Suitelet as an “API” to retrieve some Job data out of NetSuite and display on an external website using JSONP. I want to build in some rudimentary “authentication” and so I’ve developed a mechanism of passing a section of the requesting webpage’s DOM over to the Suitelet as a query string via a GET request. The Suitelet would then determine if the request came from the expected domain (we’re aware this can be spoofed by other means such as a curl request) and then validate the construction of the passed DOM snippet. Within that DOM snippet is an
img
tag whose source points to a transparent PNG file. The Suitelet downloads the file, base64encodes it and the produces a hash using another identifier as a salt. This hash is compared to the known value for this hash contained in NetSuite already. If they match then the request is considered verified and responded to. On a daily basis, we generate and upload a new, slightly different transparent image to a specific folder in NetSuite, which kicks off a process of generating a new hash from the new file, uploading itself to an S3 bucket where it will overwrite the previous version but keep the same name. This URL is hardcorded onto the external webpage which is always receiving the most recent version and so the hashing process should match. My question is can anyone see any obvious flaws in this auth flow that I may not have considered.
m
Why not just use an API key?
m
Oh. I should have mentioned…because this request isn’t happening server side…it’s happening in JS on the client side.
Unfortunately, it’s an e-commerce site builder scenario where we don’t have access to the server side, but we can attach custom JS.
m
Is the content your are displaying need to be secure is it more like whoever knows the link can view it?
m
It’s certainly not launch codes or anything, so it’s not so much an issue from the point of who can see the data. It’s more so attempting to protect the endpoint being hit by our customers who might be savvy enough to automate access away from the site.
b
It kinda sounds like you are authenticating based on if the user has access to an image
👍🏾 1
m
at it’s core yes @battk. they wouldn’t be able to pass the image directly because the download will happen on the NS side and CORS is in place to prevent direct download from any other domain (unless through a browser)
I realize this has a degree of “hackability” but because there is the need to know what segment of the DOM is being sent, the fact that the image within that DOM segment is the thing being used to validate, and they would need to know the salt phrase too, the effort to hack it might be a deterrent.
bearing in mind that on the site, there isn’t a gaurantee that there will be a “logged in” user so using those tokens is also out as an option.
the other security aspect we’re banking on is the fact that the Suitelet is limited to a GET call. Nothing non-destructive can happen via the call. The query string would be sanitized on build before the Suitelet is called.
b
Im not really sure where you are doing crypto
m
in the Suitelet
The Suitelet is checking for the presence of the image url in the DOM snippet. Downloading the file and then encoding it so that it can produce a hash from it.
b
And what is stopping people from downloading your image?
m
CORS stops that at least on the browser side. But that just prevents hotlinking
The image url could be passed in a request to the Suitlelet, but that would fail because it doesn’t have the surround DOM elements that the Suitelet is checking are present
b
I thought the request would contain an actual image
m
My thinking is that if someone constucted say a curl request, they would need to have the Suitelet URL, the specific section of the DOM that’s being passed to the Suitelet, and the entire HEAD section which would also be passed as a query parameter. The salt that is used for the hash is an element in the HEAD section. They’d have to know that.
No. The request will have a snippet of the DOM which has the transparent image as one of the elements.
b
As far as i can tell. Your security is the same as whatever is protecting your DOM
m
which is cool with me @battk. the main challenge we wanted to solve is validating that the request has only come from that webpage.
If you have access to the page then making the request is not a problem.
We want to try to reduce the chance of processing a request coming from something other than that page.
b
As in id get a headless browser, login to your site
Then send the Dom servereside
m
which is a technical know how pretty far outside the knowledge base of our clients that would be using the site.
I’ve definitely considered that access option.
b
Id personally be lazy and have your suitelet implement basic authentication
m
but then the credentials would be visible in the client-side JS
b
Your dom is visible too
m
yes. but the user wouldn’t know upfront which portions of the dom are beng used to create the hash
b
Wouldnt the js contain what dom is sent
m
yes. but the suitelet is what is pulling the specific element out of that dom snippet, and it still isn’t the dom element it’s using - it’s the file src of a single element. the dom snippet has several nested elements. the user would have to know which one.
b
What builds your query string containing dom
m
plus this file would continually rotate to a different version. it would have the same file name everytime, but the transparent png it links to might change in total pixels or dpi which would produce a different hash
the query string would be built on the client side
b
That query string is basically your password
m
<div><img src="some_file" /><img src="some_other_file" /><img src="some_different_file" /></div>
something like this would be passed as the query string that represents the snippet. only the url from one of these would be used to download the file.
b
Does the query string change on refresh on the page or something
Im assuming the code to generate your querystring is public
If so your user doesn't need to know which part of the dom is needed
m
the query string is appended to the Suitelet call, not the page request
and no, the user wouldn’t be seeing which part of the DOM is sent unless they look at the JS. and they wouldn’t know which part of the DOM is used unless they had access to the Suitelet code.
b
They can see the js
m
on the suitelet?
b
Which generates the query string
Clientside
m
so a User could go to the Suitelet directly and then see the JS there?
b
Or is the query string generation done serverside?
m
The client side JS on the external website is doing a getElement call for that section of the DOM and appending it as a query parameter to the Suitelet call
it’s also doing a getElement call to retrieve the
<HEAD>
of the DOM and sending that as a second parameter
b
A user understanding javascript will be able to understand how the url to the suitelet is generated
m
Understood
b
A user understanding the console network tool (probably the same as users knowing javascript honestly) can see the url their browser is sending requests too
m
Your saying that as long as they pass the right DOM section in the head the remaining work on the SUitelet side is irrelevent
I gotcha.
b
Its why i say be lazy and do basic authentication
m
and don’t worry about the inclusion of the credentials for basic authentication existing in the client JS?
b
Pretty much
m
gotcha