Secure a serverless backend with AWS Lambda - javascript

I currently have a website hosted on Pages, a Cloudflare service that is used to host frontend websites. This service does not allow me to execute code in the backend.
I am currently trying to implement a contact form and need to receive the messages on my personal email when someone fills out the form and submits it. To do this, I have created a lambda function on AWS and exposed it through an HTTPS URL.
The JavaScript on my frontend sends an HTTPS post request to the lambda function with the message, and this lambda function publishes the message to a SNS topic where my email is subscribed.
In the lambda function, I have set CORS to only accept HTTPS requests from my domain name. However, an attacker could potentially fake the headers of the HTTPS request, obtain the lambda URL from the source code of my website, and start calling the lambda function.
What can I do to secure the lambda function and ensure that it only accepts HTTPS requests made by the frontend of my website?
Thanks!
I have been considering moving my frontend to a serverless service like AWS Amplify, but I am not sure how to secure the calls to my lambdas since the JavaScript on my website in the user's browser is making the calls.

You can't.
HTTP is a stateless protocol. Similarly, you can't do this for any other web service (Lambda or not).
JavaScript applications run in the client's browser, so any user can inspect your application, search for any hard-coded keys, and use those to craft an API request using curl, or an HTTP library in any programming language. Clients are insecure by design.
If you want to protect your Lambda Function against unauthorized API calls, you'll need to Authenticate and Authorize your Users (here's a primer). This means you'll need to implement User Create/Login/Logout, issue cookies, and authenticate & authorize each request.
In Lambda specifically, this can be done with AWS Cognito, Auth0, or others combined with API Gateway, using a Lambda Authorizer - or implemented directly in your function.
Identity & Access Management is an entire sub-discipline in web application development, so there's a lot to learn here. I'd suggest starting with any popular library in the language of your choice, and learning from there.

Actually, Cloudflare Pages does let you execute server-side code, using Pages functions. You could use a function for taking in the form data, for example, and MailChannels integration for sending. There is also a Discord Server where you can learn how to do many things with Cloudflare Pages, both frontend and backend.

Related

HTTPS Post request in Ionic 3

I'm working on an Ionic 3 application which requires me to send encrypted data over internet to AWS lambda function. I have a API created for this lambda function and I'm able to send a post request to the lambda function using ionic's http plugin. But we can easily track the post requests send from the current configuration of my application in the Network logs.
So how can I send my data from app to AWS lambda function in a secured way?
I read about the SSLpinning in http plugin but is this the only way to approach the issue?
The problem with encrypting in the app is, that it's not that hard to make reverse enginering to see how it is made.
It's a little harder to crack if you get a key from the server at login (or daily) and use this for encrypting.
https://ionicframework.com/docs/native/aes256/
I am pretty sure you can find other pre-made modules. Else make your own. Hackers hate custom design.
And btw - https-communication to be sure it's actual is you the app is talking to.

Web API Security Information Request

I would to ask a few questions to better understand some procedures. I'm trying to write a web api project which will be a backend for both web and mobile clients.
The problem that i've in mind is about security. I don't want to use Identity or any other providers. I want to use my own database user and role structures.
Only authenticated client applications should be consuming my application. So that anonymous applications should not consume it.
So what should be the approach ? I 've written a custom AuthorizationAttribute and check some custom headers like "AppID","AppSecurity" key which i store in my own database and if the client sends the right appId and the key it means the app is authenticated to consume the API which does not sound very secure to me.
Another issue is that ; Lets say i've developed a javascript web application and i've to first authenticate the application itself before making GET/POST/PUT/DELETE etc requests which means i've to add some kind of authentication data like username, appkey, password in one of the js files for sending the "AppID" and the "AppSecurity" keys in the header. A client who knows how to use some developer tools or fiddler can easily capture my header values that are being sent to the server side? Even if i pass authentication values on the body of my json request it still can be found on the js files that are sent to the client. I'm also confused about that tooƧ
So basically i want to build a server side api that will serve the data and get data from the authenticated client applications only. What i need is a simple example for that without using any identity providers.

3rd party API service - web security and AJAX

I'm trying to create a web application which will have a component to retrieve 3rd party data from Twitter. Assuming that I've registered my application with Twitter and have a token:
Is the preferred location to store my token on my server side code (I'm using Node / Express for my backend)? The alternative would be to store it on my client side code but that seems really dangerous since everyone would be able to inspect my code.
Assuming that I do store my token on the server side, does this mean that if I want to make AJAX calls to the 3rd party API (i.e. Twitter), the flow of the request would be from client to server, and then server to 3rd party web service?
If the above case is accurate, then would my server side code have to include some asynchronous callback / promise logic such that once the data is ready from the 3rd party web service, the server will execute my callback to send the data back to the client side?
This answer makes the assumption that you are using Twitter's "application-only authentication" to make API requests on behalf of the application itself (https://dev.twitter.com/oauth/application-only).
Your server side code is the preferred location to store any API keys you do not wish to make public. The developer guidance from Twitter states "These values should be considered as sensitive as passwords and must not be shared or distributed to untrusted parties."
Yes, using an authentication model like Twitter's "application-only authentication" would require that all third party API requests be proxied through your server side code in order to protect the API token. The same is true for any third party API that requires a simple, static API key to be passed with each request.
Although it may not technically be necessary, use of asynchronous operations on the server side when making third party API requests is preferred. This will give you a more robust architecture for dealing with the instability of internet requests as one benefit.
If you intend to read or post Twitter data on behalf of visitors to your website, be sure to read more about other methods of obtaining access tokens for use with Twitter: https://dev.twitter.com/oauth/overview. For example the "3-legged authorization" method is better suited to this scenario as it provides a secure way for the end-user to supply their Twitter credentials and authorize use of their data by the requesting application.

Signing webservices api calls with javascript

I'm looking for a nice pattern that woud help me to fully sign my api calls with javascript (here for some example, vimeo) after some oauth connect retrieved authorization identifiers.
Using ruby with omniauth, what I'm looking for would be to retrieve the url that gets called when you do a ModelName.{generateTokenMethod}.request(:get,{url})
It is possible. There are a handful of oauth 1.0a libraries for javascript (You could try looking at some node.js code as an example).
The problem with using oauth in client-side javascript is that it will expose your client secret to anyone using your web service.
Anyone who has your client secret can make requests on behalf of your application, and lure users into generating access tokens by masquerading as your application.

How to protect a private REST API in an AJAX app

I know that there are many similar questions posted, but none of them refers to an HTML/javascript app where the user can access the code.
I have a private REST API written in nodejs. It is private because its only purpose is to server my HTML5 clients apps (Chrome app and Adobe Air app). So an API key is not a good solution since any user can see the javascript code.
I want to avoid bots creating accounts on my server and consuming my resources.
Is there any way to acomplish this?
An API key is a decent solution especially if you require constraints on the API key's request origin; consider that you should only accept an API key if the originating web request comes from an authorized source, such as your private domain. If a web request comes from an unauthorized domain, you could simply deny processing the request.
You can improve the security of this mechanism by utilizing a specialized encoding scheme, such as a hash-based message authentication code (HMAC). The following resource explains this mechanism clearly:
http://cloud.dzone.com/news/using-api-keys-effectively
What you want to do is employ mutually-authenticated SSL, so that your server will only accept incoming connections from your app and your app will only communicate with your server.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. If you're using Android, you can use the keytool included with the Android SDK for this purpose; if you're using another app platform, similar tools exist for them as well. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
If someone/something other than your app attempts to connect to your server, the SSL connection will not be created, as the server will reject incoming SSL connections that do not present the client certificate that you have included in your app.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android (I'm not as familiar with how to do this on other mobile platforms), both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.

Categories

Resources