Deny access from particular environments in node.js and express - javascript

Is it feasible to make access from particular environments, such as countries, operating systems, and browsers denied in Node.js and Express? I'm now constructing a web service, but must implement such filters before launching it for some reasons.
I use Node.js v0.10, Express v3.x, and would deploy on heroku. So here's my question:
Is it feasible to implement such filters in my deploy environment, and if it is, how can I do?
Is it feasible to implement such filters only on some specific services, such as comment sections?
I also wonder how secure and robust it can be to have access from those countries denied successfully.

(This is not a heroku question, and in my humble opinion not a node nor javascript question well. This is more likely an http and/or tcp question).
You can filter by these, but beware: it is not secure at all.
Detecting the user's country is usually done by ip (which you can get with req.ip) which is later converted to a location (with some ip/geo service, e.g. MaxMind).
Detecting the browser is done with the User-Agent http header. This is accessible with req.headers['user-agent'].
Detecting the OS is also done by parsing the user-agent header. There are other ways of doing this (passive os fingerprinting -- http://lcamtuf.coredump.cx/p0f3/) but these are probably not deploying on Heroku.
Note that in order to avoid filtering by country, the user can simply access your web server using a proxy in an allowed country. Also, since user-agent is a string the client sends, they can send whatever they want and fake any browser/os.
It really depends on how strict your "filtering security" requirements are.

Related

How to secure the source code of react native application?

I am building an application that has auth system and a lot of post requests,
I want to know how to make my backend endpoints accept only requests that are coming from my application, not from anything else like Postman.
For example, if a user submitted a registration form, a post request is sent to my backend with user info, how can I make sure this post request is coming from my application?
What I was thinking of, is saving a secret on the client’s side that is to be sent with each request to the backend, so that I can make sure the request is coming from my app.
I think SSL pinning is meant for this.
I know that anyone can access my app source code if they extract the APK file.
I want to make sure that no one can alter or steal my source code.
I read that I can make my code unreadable by Obfuscating it ( I still need to figure out how I am going to do that on my EAS build ), is this enough?
And I have to use JailMonkey to detect if the device is rooted.
I am using Expo secure store to save my sensitive info on the client side.
Is this approach good enough, is there anything I am missing?
I have zero information about security, this is just what I learned through searching.
Let me know if you have better suggestions.
Thank you in advance.
The Difference Between WHO and WHAT is Accessing the API Server
I want to know how to make my backend endpoints accept only requests that are coming from my application, not from anything else like Postman.
First, you need to understand the difference between WHO and WHAT is accessing the API Server to be in a better position to look for a solution to your problem.
I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
So think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
When you grasp this idea and it's ingrained in your mindset, then you will look into mobile API security with another perspective and be able to see attack surfaces that you never though they existed before.
Certificate Pinning and MitM Atacks
What I was thinking of, is saving a secret on the client’s side that is to be sent with each request to the backend, so that I can make sure the request is coming from my app. I think SSL pinning is meant for this.
Certificate pinning on the mobile app side serves to guarantee that the app is talking only with your API server and not anything else, like when a MitM attack occurs and the app has its requests intercepted, and potentially modified and/or replayed, or simply saved to later extract the secrets from it.
Pinning doesn't guarantee to your API server that the request is coming indeed from what it expects, a genuine and unmodified version of your mobile app, "unless" you implement mutual pinning, that isn't encouraged to do so, because you will need to ship the private key for the API server certificate in the mobile app. Even if you do so, all an attacker needs to do is to extract the private key and will be able to communicate with your API server like if it was your genuine mobile app.
I don't have an article to implement pinning on a react-native mobile app but you can take a look to the one I wrote for Android to understand better all the process. Read my article Securing HTTPS with Certificate Pinning on Android on how you can implement certificate pinning and by the end you will understand how it can prevent a MitM attack.
In this article you have learned that certificate pinning is the act of associating a domain name with their expected X.509 certificate, and that this is necessary to protect trust based assumptions in the certificate chain. Mistakenly issued or compromised certificates are a threat, and it is also necessary to protect the mobile app against their use in hostile environments like public wifis, or against DNS Hijacking attacks.
You also learned that certificate pinning should be used anytime you deal with Personal Identifiable Information or any other sensitive data, otherwise the communication channel between the mobile app and the API server can be inspected, modified or redirected by an attacker.
Finally you learned how to prevent MitM attacks with the implementation of certificate pinning in an Android app that makes use of a network security config file for modern Android devices, and later by using TrustKit package which supports certificate pinning for both modern and old devices.
Bypassing Certificate Pinning
I think SSL pinning is meant for this.
The good news is that you already learned how good pinning is to prevent MitM attacks, now the bad news is that it can be bypassed, and yes I also wrote an article on how to it on Android (sorry to not be specific on react-native). If you want to learn the mechanics of it then read my article How to Bypass Certificate Pinning with Frida on an Android App:
Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.
Bypassing certificate pinning is not too hard, just a little laborious, and allows an attacker to understand in detail how a mobile app communicates with its API, and then use that same knowledge to automate attacks or build other services around it.
Code Obfuscation and Modifying Code
I know that anyone can access my app source code if they extract the APK file. I want to make sure that no one can alter or steal my source code.
Sorry, but once you release it to the public is up for grabs for everyone, even if heavily obfuscated its still possible to modify it statically or during runtime.
I read that I can make my code unreadable by Obfuscating it ( I still need to figure out how I am going to do that on my EAS build ), is this enough?
No, you can use the best obfuscation tool, but then an attacker well versed in deobuscation techniques will be able to understand your code and modify it statically or at runtime. Several open-source tools exist to ake this easy, and if you read the article to bypass certificate pinning then you already saw an example of doing it at runtime with Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
RASP - Runtime Application Self-Protection
And I have to use JailMonkey to detect if the device is rooted.
Using Frida the check can be modified to always return that the device is not rooted. Also JailMonkey may not detect all ways used to hide that a device is rooted, and this a moving target, because hackers and developers are in a constant cat and mouse game.
Sensitive Info Security
I am using Expo secure store to save my sensitive info on the client side.
Even when a secret is securely stored it will need to be used at some point, and the attacker will hook Frida to this point and extract the secret or do it in a MitM attack.
Possible Solutions
Is this approach good enough, is there anything I am missing?
From all I wrote it looks no matter what you are doomed to failure in properly secure your sensitive info and to guarantee that your API server knows that what is making the request is the genuine mobile app it expects, but security its all about of applying as many layers of defences as possible, like done in medieval castles, prisons, etc., because this will increase the level of effort, time and expertise required to succeed in an attack.
You now need to find a solution that allows you to detect MitM attacks, tampered and modified apk binaries, Frida present at runtime and that can deliver a runtime secret to mobile apps that pass a mobile app attestation that guarantees with a very high degree of confidence that such threats are not present. Unfortunately I don't know any open-source project that can deliver all this features, but a commercial solution exists (I work there), and if you want to learn more about you can read the article:
Hands-on Mobile App and API Security - Runtime Secrets Protection
In a previous article we saw how to protect API keys by using Mobile App Attestation and delegating the API requests to a Proxy. This blog post will cover the situation where you can’t delegate the API requests to the Proxy, but where you want to remove the API keys (secrets) from being hard-coded in your mobile app to mitigate against the use of static binary analysis and/or runtime instrumentation techniques to extract those secrets.
We will show how to have your secrets dynamically delivered to genuine and unmodified versions of your mobile app, that are not under attack, by using Mobile App Attestation to secure the just-in-time runtime secret delivery. We will demonstrate how to achieve this with the same Astropiks mobile app from the previous article. The app uses NASA's picture of the day API to retrieve images and descriptions, which requires a registered API key that will be initially hard-coded into the app.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
short answer you can't.
I want to know how to make my backend endpoints accept only requests
that are coming from my application, not from anything else like
Postman
the only thing you can do here is cors Cross-Site Request Forgery Prevention. Y to stop other servers from calling your api.
and you can't make only your application communicate with the server
you can hard code(parameters in the request) in the application to send to the server.but hackers can listen to request made from devices
I know that anyone can access my app source code if they extract the
APK file. I want to make sure that no one can alter or steal my source
code.
short answer you also can't
you can use ProGuard(native code) to obfuscate on native android and ios have compiled binary on release but those are not to js
so basically anyone can read your bundle js in plain text editor.
maybe in the future facebook can make something for hermes.

Using Active Directory (with LDAP) to authenticate on an angularjs/javascript fronted - what should the flow of the process be?

I'm working on a project in which we need to authenticate the user in an application by using his/hers windows credentials. Frontend is using Angularjs and backend java.
After doing a sensible amount of research, I discovered that there is no way on the the frontend to obtain directly the Windows user & pass due to security concerns.
But I'm thinking that the whole process should start here, from the frontend, by obtaining these two encrypted credentials or at least a token and sending them to the backend in order to kickstart the ntlm authentication process.
And also, not sure if the user should have to log in the app by typing his windows credentials or if it should automatically be done with ntlm passthrough.
I do not have a good grip on the concept, and that is because most of the related sources that I found are referring to backend solutions (C# 80% of them), but almost nothing for fronted. So, I humbly require some clarifications on this topic. Is there some sort of middleware or npm package that I should use in order to obtain the user & pass, or what would you advise?
Web servers expose certain server variables to code handling requests they serve.
For me, using IIS, these are described here: https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524602%28v%3dvs.90%29
Since I am using IISNode; my node.js environment is completely embedded into IIS; I have access to these server variables. As the link described, each programming language seems to have their own way to access these variables.
So I would doubt it if Java does not have those as well. The exact code to use will depend on you back end.
But a quick search for "java server variables" already yields me the following:
https://docs.oracle.com/cd/E19534-01/820-3288/gawim/index.html for the java access manager.
http://users.polytech.unice.fr/~buffa/cours/internet/POLYS/servlets/Servlet-Tutorial-CGI-Variables.html for old school JSP.
How can I obtain server variables using apache wicket 1.54? for java wicket server.
So have a look at the documentation of your specific web server software or Java API.
There should be a list and example code of how to access these.
Once you obtain this data server side, you can do the LDAP query and then return the results client side.

Can WebSocket be an alternative to a Java applet?

Is it possible use the WebSocket API of JavaScript, to communicate with a native application, on the client side, like an alternative to an applet, which have to access to the file system?
I will communicate with the client side by ws://localhost:xxxx, but I don't know if I could do it.
And If I could, this will be secure. Will I have to take some security considerations?
No, you can not install a WebSocket server on a user's machine to replace the functionality of accessing the local filesystem in the same way that Java applets would.
Not without the user actively installing the WebSocket server on their own machine intentionally.
Your biggest problem is that the Javascript client code does not have unrestricted access to the user's filesystem. This is a security feature. This is an important security feature. You can not place arbitrary files on the user's machine in arbitrary places.
After that, Javascript client code also can not start processes on your system, even if it could get a WebSocket server installed in an arbitrary location. Again, this is a critical security feature.
And finally, if your Javascript client code could install and execute arbitrary software on the user's machine, you wouldn't need a WebSocket server for the use case you're looking for right now.
If you were to convince a user to install a WebSocket server on their own machine for your use case, which is to access the user's local filesystem, then you would have major security concerns to take into consideration. Not all filesystems have user and group based read/write/execute permissions... and even then, the user might start the server from within a privileged account.
The browser is designed to implicitly trust the server that it's attached to as far as whatever Javascript it receives. If your user later browses a malicious site which knows about your locally installed WebSocket server, and what commands it might expect, the browser will quite happily allow the malicious server to send any commands to your user's WebSocket server that they wish.
With my strong personal recommendation to respect the sanctity of the user's filesystem and obey the restrictions that browsers place on Javascript clients access to the local machine, if you do decide to try to convince your users to install a local WebSocket server, you must take absolute care to be as security conscious as possible. Validate *all* input, regardless of whether you think an attacker can't possibly generate it, and never blacklist known risks, ONLY whitelist known safe functions.
Remember, if you do anything to expose the user's filesystem to the web, you are pretty much handing the keys to their computer over to anyone who can find the door.

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

Cross Domain Request to localhost

DISCLAIMER: I've already looked at various approaches to solve my issue, so please read this before labeling this as a duplicate question
I have a javascript running on https://xyz.com which has to retrieve information from an application ABC running on the user's local machine say port 8080.
My constraints are that I cannot modify the HTTP headers emanating form the ABC nor do I want the user to install another application which will be a conduit to route my requests through to ABC.
Cross-Domain/Window Messaging Options
a) window.postMessage: Ruled out since I cannot have script running on the local machine
b) XDR Object (IE) or Access-Control-Allow-Origin (Firefox,Safari et al): Ruled out since I cannot modify the header
c) JSONP: Again this will not work since I am unable to enclose the response within the function name
As a workaround, only meant for testing I've added the http://xyz.com to the trusted list and have enabled Access Data Across Domains for sites on this list. AFAIK, this option is only available on IE 5+ browsers. This workaround allows me to send and receive messages from http://127.0.0.1:8080
My question is two-fold
1) If I were to continue with the above approach when I go into production what are the security implications that I'm exposing the user to? Can I plug those holes?
2) Are there any other options that I can pursue to achieve my objective.
PS: I would like to be as far away from ActiveX or Flash as possible, but in case that is the only workable alternative to my current approach then I'll have to toe the line
Cheers
If the local application could serve a single html document, to act as a bridge, then you could easily use Cross-Document Messaging (for instance with easyXDM) together with ajax requests from this document to do this. This is a very simple approach and one commonly used.
easyXDM actually comes with such a document, you can read about it here.
I think that the easiest would be to put a server script on https://xyz.com which will act as a bridge between the javascript file and ABC. Then the javascript file will simply send an AJAX request to it's own server script which will take care of fetching the information from the remote domain. The only other viable solution which would work among most browsers and which doesn't require using some client technology like Flash or ActiveX is JSONP but you have ruled this out because you have no control over the remote domain.

Categories

Resources