Protecting "back-end" angular source files - javascript

I have a Angular system that solely talks with my Go back-end and with Gorilla I take care of my sessions for login.
I started working on my admin environment, but I wondered what would be best practice for protecting the angular code for it. It's not really a problem for security because even the admin code will just have logic, and not dangerous data, still I prefer to not have it open to just anyone in the world.
I was thinking of doing the following;
I have a mux router that catches all my resource calls (deployment with Yeoman) and I was wondering that I would make 3 exceptions there for images/admin, scripts/admin and styles/admin. These paths can then only be served if you have a valid session active. Otherwise throwing a 401 header.
Would this be a good solution or is there a more efficient way to achieve this?

If you need a valid (and preferably authorized) session to get some static assets (being them JS code, stylesheets, images...), you need to pass through the application, the stack you use is not relevant at all.
What I'd do is to point the resource to something controlled by your application, and then return either a 401 or an empty response with a X-Sendfile or X-Accel-Redirect header so the actual serving is offloaded to whatever reverse proxy you have in place.

Related

Issue with Adblockers on server-side GTM

I am using Server side GTM, but I am facing adblocking issues when calling the below request when I want to retrieve the gtm?js file:
https://example.gtmdomain.com/gtm.js?id=GTM-MY_GTM_ID
The request works fine when I don't use adblockers.
Is there a way to rename the endpoint to something else, such as https://example.gtmdomain.com/secret_file_name.js?id=GTM-MY_GTM_ID in order to not be blocked by adblockers?
So. Server-side gtm is exactly what it says. It's executed on the server. It listens for network requests. It doesn't have any exposure to what happens on the front-end. And the front-end has no clue about there being a server-side GTM. Well, unless there are explicit calls to its endpoint, which you can proxy with your backend mirrors when needed.
What you experience is adblockers blocking your front-end GTM container. Even though it's theoretically possible to track all you need, including front-end events with server-side GTM, it's considered to be the best practice to use both GTMs and stream front-end events to back-end GTM through front-end GTM.
This, of course, makes you dependant on adblockers since they will block your front-end GTM. A way to avoid it is... Well, not to use the front-end GTM and have all your tracking implemented either in a tag manager that is not blocked (I doubt there is one) or just have your own custom javascript library doing all the front-end tracking and sending it to the backend GTM to be properly processed and distributed.
Generally, it's too expensive to implement tracking with no TMS, since now you really have to know your JS, so only the cool kids can afford to do this. A good example would be Amazon.
Basically, it would cost about two to five times more (depending on particulars) to implement tracking with no TMS, but adblockers typically cut only about 10% of traffic. 10% is not vital for reporting, measuring effectiveness of funnels and what not. All the critically important data is not being reported on by analytics anyway. Backend is the real source of critical data.
You can easily do this if you use sGTM hosting from https://stape.io
There is a feature called Custom Loader. With it, you can download Web GTM from different paths and all other related scripts will be also downloaded from different URLs, for example, gtag.js for GA4.
More info https://stape.io/blog/avoiding-google-tag-manager-blocking-by-adblockers
You can also create your custom loader client for Web GTM. However, there will be problems with related scripts. UA/GA4 still will be blocked then, but GTM itself not.
So, I finally implemented a great solution using GTM client templates. It works like a charm.
To summarize, the steps are:
Create a client template from your server container. You can import this template from https://raw.githubusercontent.com/gtm-templates-simo-ahava/gtm-loader/main/template.tpl
Create a new client from this client template
name your path as you want
This article explains perfectly the required steps: https://www.simoahava.com/analytics/custom-gtm-loader-server-side-tagging/

How do I correctly deal with 404 HTTP errors when using an SPA and no server-side computation?

I am currently using Vue.js on a website project of mine.
The server that returns this Vue.js SPA will not be capable of computation or checks, and will only serve the static resources required to run the SPA in the browser, where all computation will then take place.
For SEO purposes, I want to ensure error pages are handled correctly. Currently, every URL returns a 200 OK and serves the SPA which can confuse search engines for pages that are actually supposed to be invalid. What would be the correct way of telling both users and search engines that the page is invalid if I cannot change the response the server provides?
For context, the SPA will get data from an API on another domain.
I have looked at other questions that are similar, but they normally recommend server-side checks, a dedicated 404-page redirect or a soft-404 page. Server-side checks and a dedicated 404 page will not be possible, and I have read that soft-404 pages are disliked by search engines.
Is there any proper way to go about this?
I have seen this post, but it is quite old and only suggests a no-index tag, which still makes the page valid in the eyes of search engines, just not indexable.
You can't return a 404 error without any server-side computation/rendering, because the fact that the resource/page wasn't found relies on some logic that only gets executed on the client-side in your case. Hence, your only options are the following:
If the resource wasn't found, redirect the user to a pre-defined 404 page (that returns the correct HTTP status)
Blacklist paths that are invalid inside your proxy, or whitelist those that are valid, and proxy to a 404 page on all other paths
Manually create a sitemap with your valid pages/routes
None of these options are optimal if your project grows or you have dynamic routes, but those are the limitations of client-side rendering. Hence I don't think there's a good answer to your question, since this is a well-known limitation of client-side rendering, and one of the main reasons why projects that care about SEO prefer server-side rendering.
From an SEO perspective: As long as you add all your valid pages to a sitemap, and don't link (anchor tag) to the invalid ones on any of your other pages, no search engine crawler will ever crawl or index these pages.
But if you really care about SEO and have a dynamic app with hundreds/thousands of dynamic links that cannot be added to a sitemap manually, I'd advise you to switch to a production framework like Nuxt.js or Next.js because they offer what you're looking for and much other SEO features out of the box.

Questions on Security in React.js

I am building my first application on React.JS and I am wondering how to implement simple security in on the client-side because there are some vulnerabilities that I see such as if you view page source the script tags show you all the Components that you made with all the functioning and rendered pages, Also if there is a basic method to stop XSS from happening that I can build on I would like to see that as well.
I am concerned about how anyone can view a page source on react and see the components from the script tag
You're not going to be able to prevent people from looking at the code source on the browser, since the browser has to see it and render it. You can make it a little harder for people to get to the inspect element, but there is always a way to get to it.
As for XSS, all you can do on the client side is validating input and sanitizing, but you can get around that via watching the network traffic and submitting bad data directly through your own http requests.
Client side is just that, served to the client.
What do you mean by sources? It's still a JavaScript and everybody can see the sources, but they will be uglified and minified by Webpack.
Regarding XSS. Don't worry about it using React. Your code is already protected thanks to JSX. String variables in views are escaped automatically.
I suggest you to secure you're service in back-end, because anyone can request to the server trough Postman and can record and repeat your request in BurpSuite;
then use security solutions in your back-end code after that use Object Schema validator in your React app to prevent users XSS attacks.

Single page web app (SPA) link/refresh routing design considerations and caching

What is the recommended practice of sending the SPA code to the client with routing considerations? How to send the SPA code to the client when they go directly to a link (e.g. website.com/users/user1) rather than the root path first.
An example best illustrates the question:
The path website.com/users/user1 responds with some application/JSON so that the SPA can fill in the layout with the information.
Let's say that you have a basic SPA and you are making a request on website.com/users/user1 (assume no auth is required) without having first visited the root path where it is clear that we can send the SPA code (html, css, javascript) to the client and then they can make their requests to the different routes through the web app. So the user visits websitename.com/users/user1 and the server doesn't know whether the client needs all of the SPA code first or just the JSON (maybe the most recent version is cached, or they are visiting website.com/users/user1 after having first visited website.com/ which knows to make a specific request to the server and ask for the JSON).
How is this typically handled? Is a flag, date, or something else sent to the webserver with the SPA so that the server knows the client has the SPA code? This could be done via the SPA requesting a content type of application/json on the route rather than a standard GET request? Or setting a header that the SPA sends back denoting its most recent version (this way we can use caching and if it isn't the most recent, or there is no SPA yet, a new version may be sent).
How is it recommended that the SPA handle this? Does the SPA check the URI and note that it has only just received the SPA code from the server and not the actual content from the server (e.g., user1's information). And how is it recommended that we check this? The server sends back the SPA code and sets a header denoting that the SPA needs to make another request to website.com/user/user1 to actually retrieve the actual JSON of user1's info rather than the SPA code.
EDIT: I have eventually come across this SO question and the answer more or less addresses all of my questions: How to make a SPA SEO crawlable? There are obviously many ways to handle this on both client and server side and I wanted to see the different ways people addressed the issue. (I like the way that the aforementioned question/answer deals with the issue and will likely use a similar scheme.)
I don't know what your stack is, and I can't really speak to recommended practices, but I use webpack for this. In webpack, you accomplish this by defining multiple entry points. This splits your code into different self-contained packs, so you can have different .html files that produce different code bundles.
Adapting your situation to the appropriate webpack config:
{
entry: {
main: "./index
user1: "./users/user1",
},
output: {
path: path.join(__dirname, "dist"),
filename: "[name].entry.js"
}
}
Then, in the appropriate html, you'd load user1.entry.js
I am not sure how extensible this is for a situation where each of your users has their own dedicated URL (obviously you can't name a unique entry point for hundreds of users), but at that point I'm not sure what you have is technically an SPA.
You can also consider using a routing solution similar to react-router, which allows you to grab data from the URL. eg, w/ a webpack config like above, navigating to example.com/users/user1:
users.html/users.js:
loadJSONFromServer({url-user-id})
I believe what you are asking is, how does a user visit a page that is not the home page (maybe through a link that was shared) and the app get the data it is supposed to display on that page.
They way I typically accomplish this is to initiate a data fetch in the lifecycle method componentDidMount that evaluates what data is already present, and fills in the missing pieces. You could accomplish something similar through react-router's onEnter hook (which is how I handle user auth in an SPA).

How can I check if an XMLHttpRequest to my public API is from my own webapp or from a third-party client (to ensure priority)?

Does anybody know of a way of checking on the API side if a XMLHttpRequest has been made from my own web-application (ie. from the JS I have written) or from a third-party application...
The problem, to me, seems to be that because the JS is run on the client and thus accessible to anyone I have no way of secretly communicating to the API server who I am. I think this is useful because otherwise I cannot prioritize requests from my own application over third-party clients in case of high usage.
I could obviously send some non-documented parameters but these can be spoofed.
Anybody with some ideas?
I would have your web server application generate a token that it would pass to your clients either in JavaScript or a hidden field which they in turn would use to call your API. Those with valid tokens get priority, missing or invalid tokes wouldn't. The web server application can create & register the token in your system in a way that limits its usefulness to others trying to reuse it (e.g., time limited).
If you do approve of third party clients accessing your API, perhaps you could provide them with a slightly different, rate-limited interface and document it well (so that it would be easier to use and thus actually be used by third-party clients).
One way to do this would be to have two different API URLs, for example:
/api?client=ThirdPartyAppName&... for third-party apps (you would encourage use of this URL)
/api?token=<number generated from hidden fields from the HTML page using obfuscated code>&... for your own JS
Note that as you mention, it is not possible to put a complete stop to reverse engineering of your own code. Although it can take longer, even compiled, binary code written in such languages as C++ can be reverse engineered, and that threatens any approach relying on secrecy.
A couple of ideas come to mind. I understand that secrets never last, so I agree that's not a good option.
You could run another instance on a different unadvertised port
You could do it over SSL and use certs to identify the client
A simple but less secure way would be to use cookies
You could go by IP address, but that could be an administrative nightmare

Categories

Resources