AWS EC2 security to only allow HTTP requests originating as a result of browser accessing static s3 content - angularjs

As part of distributed deployment on AWS, we have moved all static web assets, including angularjs files and dependencies to an AWS S3 bucket (static website). Angularjs controllers have complete API URL pointing to a nodejs server running on an EC2 instance. I am trying to figure out what is a good way to prevent Nodejs server from processing any HTTP requests other than the ones originating from angularjs controller.
Option -1 ) I cannot use S3 IP address for obvious reasons as incoming IP address for EC2 security group hosting the Nodejs server.
Option -2) I can use VPC Endpoint, but its more of a solution to allow EC2 in private subnet to access an S3 bucket.
Option -3) I can have another EC2 instance hosting a reverse proxy which the S3 angularjs will connect to. This reverse proxy will forward the request to EC2 instance running nodejs.
Option -4) Use AWS Nat Gateway, do not think its much different from option # 3.
Need folks to chime in with their thoughts keeping in mind security.

In case of AngularJS, it's all JavaScript. Your code is run from the use's web browser, not S3 bucket.
You can implement this by validating the Origin HTTP header. But that can be easily hacked.
The best possible solution is provide a service which generates some kind of session token, add it as part of all requests in some header field in AngularJS while sending requests to your NodeJS server and validate it for every request.

Related

CloudFlare JS challenge is breaking my SPA

I have a React based SPA that is hosted via S3 on one subdomain, react.mydomain.com ... It communicates with a PHP REST API that is hosted on a VPS on another subdomain, api.mydomain.com . The api.mydomain.com is behind CloudFlare. The webapp is behind CloudFront since it is on AWS.
I am having issues w/ bot requests directly to the API flooding my VPS, and I would like to use the JS challenge functionality with CloudFlare to mitigate.
However, what seems to be happening is that users are able to load the React webapp (which is not behind CloudFlare). Then, the request that will prompt the JS challenge will fail with a 503 response instantly, because it is an AJAX request and it is incompatible with the Javascript challenge.
I thought I may be able to handle this by catching the error and redirecting. However, if I manually force my own browser to navigate to the api.mydomain.com URL, I will see the CloudFlare challenge and pass it. However, if I then navigate back to my react.mydomain.com SPA, the OPTIONS requests will fail because it cannot attach the cookie that tells CloudFlare it has passed.
I don't understand how to adjust my infrastructure so that I can take advantage of using the JS challenge. At the moment I am restricted to using rate limiting, but I have found that I am still letting in what seems like ~75% or more of the unwanted bot traffic through by the time I get severe enough that users start complaining.
If you have backend access, you may be able to use NPM and process.kill(process.pid) upon detection of a bot as a temporary solution.
I suggest not to host spa in s3 only file uploads or attachments to s3
Host on Ec2 and block all access through security Group Policy
only allow Cloudflare IP's
which are listed here https://www.cloudflare.com/ips/
You can also use Amazon AWS Lambda serverless for hosting instead of s3
https://aws.amazon.com/lambda/?c=ser&sec=srv

Deploying ReactJS application on AWS S3 with HTTPS

I want to deploy a ReactJS application on the AWS S3 (which I managed to do successfully). Now I need to make it HTTPS with lowest cost possible. How can I do this? A quick google search gave me something called Amazon CloudFront I am confused over there that do I need to have a Dedicated IP SSL Certificate to deploy my react application with HTTPS ?
I have referred to this question on deployment with S3.
Thanks
If you are trying to find things in detail, You can have a quick look here. Its just 2 minute reading and cover following things.
React Js deployment with Https cloud front
Subdomain
Configure AWS CLI and deploy build through command
https://bluebash.co/blog/react-deployment-with-aws-ssl-https-with-subdomain/
Answer to Why We need to use Cloudfront is :
Note: We need to do this because SSL certificates can only be assigned to cloudfront distributions or AWS ELB, so you need to create
one to enable SSL for your static website.
There are few steps involved in this , assuming you have site properly set up with HTTP end working here are some steps :
1) You need to Request SSL Certifcate from AWS (ACM) it is free and you would not be chraged for this you follow this AWS Documentation
Enter one or more domain names, you want to create a SSL certificate
for. You can even use a wildcard.
Verify the email you will get to email address associated witht the
domain.
Note: Choose Region as per your s3 bucket as Cloudfront only accepts certificates hosted in region us-east-1
2) Now you need to create Cloudfront Distribution :
Create a new Web distribution and select your S3 bucket as Origin
Domain Name. Select HTTPS Only for Viewer Protocol Policy.
In the Distribution Settings section enter your domain name you want
to host your static files on.
Beside that keep all the default settings and click “Create
distribution”.
3) Now Assign the SSL certificate to your Cloudfront distribution
Go back to Cloudfront and edit your distribution. Now you should be
able to select your brand new SSL certificate.
Hope This Helps..

How to deploy angular app that completely relies on external API to retrieve and store data?

For an angular app that completely relies on external API to retrieve and store data, is NodeJS necessary for deployment? What are the other possible methods of deployment? Currently, I use it for local development and plan on using it in combination with Nginx for production. However, NodeJS is not doing anything except launching index.html. So should I remove NodeJS altogether and simply use Nginx alone?
One solution is to host it using any web host, they all equally host HTML only sites, and this solution is pretty inexpensive. Hosts like Hostgator, web.com etc., will allow you to upload the site via FTP.
A second choice is to host it using a web server (Nginx), but this is probably the most costly. You can host your own server in any cloud service (Amazon would be EC2 for instance) and then host your files there. This is probably not a good option for you. The only reason to use this type of solution is if you need the server to host code, so if you were using node to talk to a database for instance.
A 'pro' option may be to put them in S3 on AWS, and host it that way, it is pretty inexpensive.
Here is a link explaining how to host on Amazon - http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html
http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html

Is it possible to host an AngularJS app on Amazon S3 using CloudFront over SSL?

I'm not aware of a solution that allows you to do this using SSL on CloudFront simply because it cannot pull from S3 over SSL. Am I missing something?
Yes. You can require your CloudFront content to be served via HTTPS to your viewers, and separately have CloudFront pull from your origin via HTTP or HTTPS. See Using an HTTPS Connection to Access Your Objects
That document states:
For web distributions, you can use HTTPS requests to ensure that your
objects are encrypted when CloudFront serves them to viewers and,
optionally, when CloudFront gets the objects from your origin.
The viewer <== CloudFront is one connection, and the CloudFront <== Originis another separate connection.
Its up to you whether or not you need SSL end to end, but there is no limitation like the one you describe.

Do you really need a server for AngularJS app?

I want to deploy my AngularJS app which access RESTful web-services onto an aws and I am wondering if I really need a server to serve my AngularJS files.
I can server them as static files or use something like NodeJS but do I really need one?
What are the advantages/dis-advantages of using a server in this scenario?
If your app is small, it's really not a problem if you only access to an API.
But if you want to login via other services where you have for example a public and secret token it's better to work with a server who use cache this datas from your users (maybe it's what your aws is doing).
If you want to access RESTFull Web Services from AWS, you need to put your angularjs files in a server.
The server will give access to resources, if the request is from http protocol. It will deny the request to serve if the protocol is file.

Resources