Static website access of environmental variable: "process is not defined" - javascript

I have a static website developed through 11ty (Node based SSG), which contains a Contact form that sends a request to a nodemailer API with the data. Both are hosted on Render, as a Static Website and Web Service respectively, and they share a basic auth password which I've stored in each project as an environmental variable.
The Web Service accesses the variables just fine. However, the static website's event presents me with the error in the title "process" isn't defined, as in "process.env.VARIABLE_NAME" which is how I'm accessing them. I tried including a secret .env file in the project with the same key and including dotenv in the project, but no change.
I assume the nature of the static site is making it so the environmental variable isn't being processed/applied somehow. What possible steps could I be missing here?
EDIT: Although it seems it might be possible for me to do this through methods such as command line arguments (which then get injected into the code during the build process), that wouldn't work for my case since the password had to be secret in the generated source files. The dotenv package didn't work in my case. Finally, I've opted to discard this password-based authentication instead and simply use honeypot fields to prevent spam and CORS Origin headers in the API to control request source.

Your static site is running in a different context than your web service (which acts like a server). Since your static site is run from a users browser, it does not understand node-specific functionality like loading files or accessing your process environment.
Adding your password to your static site would also create a security risk, because a user could just see your password, take it, and run their own requests without any security your site may have.
A usual approach to this would be to create an API of your own that takes in a request from your static site and talks to the API directly or a technology stack that takes the page rendering to a server (like ServerSideRendering). This way, YOUR system takes care of calling the API while your users requests are restricted.

Related

Preventing CSRF with an Express API and a React frontend

I have been reading around CSRF for the past few days and feel like I have a good grasp on what it is and how to prevent it. I am building a small Express/React application that will have a secure admin area for updating the app content and I want it to be protected from CSRF.
I understand that it is common for the server to generate the CSRF token and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag). However, my Express API does not serve HTML, it is a REST API that only returns JSON data. The UI is built with React, running on a different port from the server.
My question is; Where do I securely store a token generated on the server?
For example, if I log in as admin by hitting '/api/login', generate a token, and send it back to the client in the API response, what should I do with it now?
The original plan was to use Redux to store the token but from reading this post Is Redux secure?, this does not sound ideal.
I considered using React env variables but have also read that these are exposed in the build.
Obviously localStorage is also a bad idea...
I am really struggling to find a solution to this problem using the tools I am implementing i.e. Express/React
Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind
I understand that it is common for the server to generate the CSRF token
The server needs to generate two CSRF tokens
and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag).
One token is commonly sent as a cookie, another can be sent as HTTP header. It doesn't need to be sent inside HTML body as a HTML form input tag (or any other part of the body) though it can be sent this way.
My question is; Where do I securely store a token generated on the server?
You don't have to store a token on the server. You can but you don't need to.
The original plan was to use Redux to store the token
The Redux store is on the client, in browser's memory. In theory one React component (that extracts the second CSRF token from server response) can temporarily store the token in the store so that another React component can get it from there and put into the next request before it's sent to the server.
Obviously localStorage is also a bad idea...
Yes
Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind
Links
With Express is very common to use this middleware. The steps can be found here.
Criticisms
This is strictly speaking off topic in the context of CSRF related Q/A, but ...
The UI is built with React, running on a different port from the server.
That hints to the possibility of using react-scripts which start webpack-dev-server. It's fine for development, not good for deployment in production. However this is a separate topic, serving React app's build artifacts (.html file, script bundles) to webclients has nothing to do with CSRF attack and its mitigation.
I want to learn to build apps with security in mind
Then you might consider using one webserver instead of two (frontend to serve React app and backend to serve API responses). Using one server results in production deployment which is not only less complex and costly, but also more secure because two servers have larger attack surface and with one server you don't need to weaken security by using CORS.

Per-page localStorage?

In HTML5, is it possible to create a localstorage that is accessible only to a single webpage?
I am currently experimenting with possibilities of writing self-contained single-page applications, and whether it is possible for users to host them themselves, e.g. on their Dropbox (which has some basic webhosting capabilities for public files) or by running a minimal webserver on localhost.
A user may then start such HTML Applications from various sources in his local server / Dropbox, or be asked to open one from another users Dropbox.
Since all these pages would be served from the same origin (currently https://dl.dropboxusercontent.com), they would all share a single localStorage, which may both interfere with the functionality if names clash, and leak data; E.g. such a page may want to store the authentication token for accessing the users Dropbox account in localStorage, but then any other such "App" would be able to steal the token.
I have to say here, that I am new to HTML5, and may very well be stretching the intended scope of usage here, as I keep running into limitations due to basic websecurity concepts like the same-origin policy – especially when opening a HTML file from a local drive through a file:// uri.
The core intent is allowing users to host their own custom apps in a manner that works across their mobile and desktop devices, by utilizing their existing webservice subscriptions for both hosting and data synchronization rather than moving their data to yet another service.
As stated here, localStorage is scoped by protocol, domain and port, nothing else.
And with this, even by prefixing each localStorage key by a unique page token (i.e. localStorage.set('page1.' + key)), it wouldn't avoid another page from getting those info, so no simple way to avoid information leak.
You can use unique page identifier (or even url) as a key for encryption of stored data. In theory.

Access the force.com REST API with a pure Javascript page

I want to develop a front-end in Javascript (possibly with one of the fancy frameworks around such as AngularJS) that consumes the REST API of my Salesforce org.
I don't want to embed my project in Salesforce technologies, so basically
no Visualforce pages
no Force.com Sites
I do want to write my own front-end on a separate server that just makes AJAX calls to the Salesforce back-end.
In addition, I want the application to be accessible for any user, even if he/she does not have a Salesforce account. So the AJAX calls should not require that the user logs in on Salesforce. I want anonymous users to be able to retrieve public data from my organization and create new entries when it is useful (in the case of a survey for instance).
Even though these requirements generate some security concerns, I can imagine that Salesforce takes care about the requests rate limits on their API endpoints and that it is possible to restrict the access to the API on a host name base (e.g., only requests with origin host my-trusted-domain.com should be allowed, send a 403-Forbidden otherwise). I would be surprised if SF does not provide such basic features.
How would you proceed? Is there a minimal Javascript code that works out-of-the-box on any domain without getting into troubles with CORS?
All REST API calls to Salesforce must be authenticated. If you want anonymous API access then you will need to proxy authenticated calls through a server (like on Heroku) that adds the auth token. Or you can use Heroku Connect to expose your Salesforce data to a Heroku app as a Postrgres database.
If you go the REST route then checkout the ForceServer and my CORS Proxy for Salesforce. Both are not setup out-of-the-box for the anonymous access you are looking for but could easily be tweaked to support that use case.
BTW: When allowing anonymous access to your Salesforce data through a proxy make sure you are dealing correctly with security and request limits.

Where to put my php file?

I am trying to make a sign up activity on android and I am using a mysql database to store the data. On all the examples I have seen the http post goes to a ip address and then finds the php file. Can I just put the php file somewhere in the android app folder and access it from there, or do I have to find a host for it?
The php code, specially for tasks such as sign up, should never be placed on the client side or embedded with the front end application, but instead be placed on the server side hidden from the user for the sake of safety of your database/application. If you are only considering to put your php with your Android app together for the case you need to test it, and eventually doesn't have access to a server, you may then consider using Google App Engine, as it allows you to emulate a server locally without the need of a server. Here you find some info about Amazon's RDS.
You can put you php in the same directory you place your index.html file, i.e. in the root public directory of your domain. To load it to the Amazon, you can use the cPanel or the Filezilla or any other panel you wish among the options Amazon put available for their users.
In the case Amazon doesn't provide a place to put your php, as a suggestion, you can get a host that allows you to have a static ip accessing it thorough an easy to remember url address - for free. It is quite useful specially for making tests. Still if you decide at some point to have a personalized domain name registered, there are also some other good options to compare.
You dont need jQuery, when doing the POST request,PHP connects to the database get the data and return it to your app.
So to answer your question you should put the PHP in the same server where mysql runs.

activate/enable javascript plugins based on user options

I'm building a JS client for a set of REST WebServices. The client will be delivered as an embeddable iframe, which should load JS scripts based on user options (license profile, user admin options, etc.)
I wonder what's the most effective and efficient pattern to do that.
At now I have a single "bootstrap" script, which includes the other scripts. I could create the bootstrap script code dynamically (server side), to make it load only the set of scripts required by the user configuration. Anyway those scripts would be publicly available, even if the services are not enabled for certain users... IMHO that's not a good solution.
On the other hand, how to control the access to static javascipt files on a public folder?
I want to avoid to serve javascript code though my code. It would be an expensive overload for the application!
Mmm... I'm a bit confused...
Giovanni
In general, if you wish to control access to a resource based on a business requirement (licenses, user profiles etc) you have no choice but to route all requests for that resource through your application.
However, since you are you are sending the files to the client there is no guarantee that anyone in possession of the scripts is currently authorized or authenticated (license may have expired, etc). As such, you cannot infer that a request to your web services is valid based on the fact that a consumer knows how to call your web service.
There should be very little to lose in making the scripts publicly accessible (since there should be nothing that you wish to kept secret in them). So, in answer to your question, I would suggest authenticating and authorizing any requests at the web service level and allowing the javascript files to be publicly accessible.

Categories