anonymous read with amazon simpledb - database

I would like to query simpledb directly from the client using javascript. My application is read-heavy and I rather not route the request through my application server. Is it possible to perform a select request without authentication?
I could set up an authentication server, but this is rather inelegant as it will just be saying yes to every read request and would introduce another bottleneck/speedbump/point of failure.
Do the other cloud db solutions (microsoft, google) have this functionality?

This is possible using AWS IAM (Identity and Access Management) and a server side "token vending machine". AWS docs have an article specifically written for the use case Authenticating Users of AWS Mobile Applications with a Token Vending Machine and sample code for server, iOS, and Android in GitHub. The general technique can be used for non-mobile and/or for JavaScript clients.
Note: a server component is still required to vend out the temporary access tokens. However, the volume of these requests can be significantly reduced (up to once every 36 hours). The remaining requests are from untrusted client to SimpleDB directly, no intermediary.
General Technique
anonymous client calls your token vending machine (your server)
token vending machine knows the secret key, calls AWS to generate a temporary token
token is created with read-only access policy (example below)
token lasts for a maximum of 36 hours, default 12 hours (api docs)
vending machine returns token to client
client calls simpleDB API using anonymous, temporary token; cannot write to SimpleDB
Read Only Access Policy
From AWS sample code "Read Only Access Policy"
{
"Statement": [
{
"Action": ["sdb:GetAttributes", "sdb:List*", "sdb:Select*"],
"Effect": "Allow",
"Resource": "*"
}
]
}
This extends beyond SimpleDB. You can set an access policy for several other AWS resources (see full access policy example).
Variation to Replace Dynamic Client-Server calls with Static Resource
Although you cannot eliminate a server component, clients don't necessarily have to talk to the vending machine directly:
scheduled job generates token every N seconds where N + fudge == token expiry
job writes token to public S3 bucket (or any other static resource)
set appropriate maxAge cache-control header based on fudge
anonymous client reads token from static URI
client authenticates with token, makes read-only calls to SimpleDB

You would need to sign all requests with your server. I think that's what you mean anyway. You could still save some bandwidth.
I'd say, as soon as a JavaScript client can authenticate itself, everyone could.

An authentication server is required, you can use EC2 for this.

Related

How to protect your API from abuse - DRF & React

I'm really struggling to wrap my head around the concept of protecting ones API end point.
How do you do you protect it from abuse if it's exposed with React?
I understand if a user were to login then be issued them with a token etc. I get that. But let's say have a front end that does not require someone to be logged in?
They simply filling out a form with their details and it gets passed via you API then gets stored in the DB.
Whats stopping someone just abusing your API? They could just write a script and attack you end point with spammy data?
I just can't understand how this is protected?
you can set CORS headers, allowed hosts and also rate limiter for protecting your APIs in Django.
Allowed hosts: A list of strings representing the host/domain names that Django site can serve. This is a security measure to prevent HTTP Host header attacks, which are possible even under many seemingly-safe web server configurations.
CORS headers: Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. It's used for working with browser clients.
Rate limiting: A rate limit is the maximum number of calls you want to allow in a particular time interval. For example each unauthenticated user can only do 100 requests per minute.
And also if you are deploying your app in a PaaS service then you can deploy your django app as an internal service and your react app as an external service. Then Django is not only usable inside the containers not outside them.

Client Side Rendering and API Security [duplicate]

I'm developing the restful web app that using some popular web framework on the backend, say (rails, sinatra, flask, express.js). Ideally, I want to develop client side with Backbone.js. How do I let only my javascript client side interact with those API calls? I don't want those API calls to be public and be called by curl or simply by entering the link on browser.
As a first principle, if your API is consumed by your JS client, you have to assume, that it is public: A simple JS debugger puts an attacker into a position, where he can send a byte-for-byte identical request from a tool of his choice.
That said, if I read your question correctly, this is not, what you want to avoid: What you really don't want to happen is, that your API is consumed (on a regular basis) without your JS client being involved. Here are some ideas on how to if not enforce, then at least encourage using your client:
I am sure, your API has some sort of authentication field (e.g. Hash computed on the client). If not, take a look at This SO question. Make sure you use a salt (or even API key) that is given to your JS client on a session basis (a.o.t. hardcoded). This way, an unauthorized consumer of your API is forced into much more work.
On loading the JS client, remember some HTTP headers (user agent comes to mind) and the IP address and ask for reauthentication if they change, employing blacklists for the usual suspects. This forces an attacker to do his homework more thoroughly again.
On the server side, remember the last few API calls, and before allowing another one, check if business logic allows for the new one right now: This denies an attacker the ability to concentrate many of his sessions into one session with your server: In combination with the other measures, this will make an abuser easy detectable.
I might not have said that with the necessary clarity: I consider it impossible to make it completely impossible for an abuser to consume your service, but you can make it so hard, it might not be worth the hassle.
You should implement some sort of authentication system. One good way to handle this is to define some expected header variables. For example, you can have an auth/login API call that returns a session token. Subsequent calls to your API will expect a session token to be set in an HTTP header variable with a specific name like 'your-api-token'.
Alternatively many systems create access tokens or keys that are expected (like youtube, facebook or twitter) using some sort of api account system. In those cases, your client would have to store these in some manner in the client.
Then it's simply a matter of adding a check for the session into your REST framework and throwing an exception. If at all possible the status code (to be restful) would be a 401 error.
There's an open standard now called "JSON Web Token",
see https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for
creating tokens that assert some number of claims. For example, a
server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to
prove that they are logged in as admin. The tokens are signed by the
server's key, so the server is able to verify that the token is
legitimate. The tokens are designed to be compact, URL-safe and usable
especially in web browser single sign-on (SSO) context. JWT claims can
be typically used to pass identity of authenticated users between an
identity provider and a service provider, or any other type of claims
as required by business processes.[1][2] The tokens can also be
authenticated and encrypted.[3][4]
Set a SESSION var on the server when the client first loads your index.html (or backbone.js etc.)
Check this var on the server-side on every API call.
P.S. this is not a "security" solution!!! This is just to ease the load on your server so people don't abuse it or "hotlink" your API from other websites and apps.
Excuse me #MarkAmery and Eugene, but that is incorrect.
Your js+html (client) app running in the browser CAN be set up to exclude unauthorized direct calls to the API as follows:
First step: Set up the API to require authentication. The client must first authenticate itself via the server (or some other security server) for example asking the human user to provide the correct password.
Before authentication the calls to the API are not accepted.
During authentication a "token" is returned.
After authentication only API calls with the authentication "token" will be accepted.
Of course at this stage only authorized users who have the password can access the API, although if they are programmers debugging the app, they can access it directly for testing purposes.
Second step: Now set up an extra security API, that is to be called within a short limit of time after the client js+html app was initially requested from the server. This "callback" will tell the server that the client was downloaded successfully. Restrict your REST API calls to work only if the client was requested recently and successfully.
Now in order to use your API they must first download the client and actually run it in a browser. Only after successfully receiving the callback, and then user entry within a short frame of time, will the API accept calls.
So you do not have to worry that this may be an unauthorized user without credentials.
(The title of the question, 'How do I secure REST API calls', and from most of what you say, that is your major concern, and not the literal question of HOW your API is called, but rather BY WHOM, correct?)
Here's what I do:
Secure the API with an HTTP Header with calls such as X-APITOKEN:
Use session variables in PHP. Have a login system in place and save the user token in session variables.
Call JS code with Ajax to PHP and use the session variable with curl to call the API. That way, if the session variable is not set, it won't call and the PHP code contains the Access Token to the API.

Is it ok to pass OAuth access tokens to the Client

i'm still pretty new to web-development I worked myself through Web Development with Node and Express by Ethan Brown and currently i'm trying to get a good understanding for the examples given by Full-Stack React Projects by Shama Hoque.
Currently i'm trying to refactor a lot of things that used to be server-side-rendered to be handled in the React SPA client. One of these things includes a simple GitHub widget, my previous flow worked like this:
The client user authenticates with my server using a GitHub OAuth app.
The server stores the access Token returned to the callback in a database on the server.
The server makes calls to the GitHub API using the user access Token stored in the database.
The server processes the results, renders it in HTML and sends it to the client.
However I realized that there is also possibility to implement it like this.
The client user authenticates with my server using a GitHub OAuth app.
The server passes the access Token returned to the callback back to the client
The client makes calls to the GitHub API using the user access token obtained from the server.
The client processes the results and renders it apropiately.
As far as I understand there is no inherent security risk doing this(a malacious user could interecept the access token when the oAuth provider redirects to the callback either way) and both flows have their up and downsides (e.g. 2nd flow produces less load on the server but also sacrifices control). Since I'm new to this and I came up with the 2nd flow myself I wanna double check if this is something thats ok to be doing or I've missed something, if so, what did I miss? Is there any other major down or upsides i'm not considering?
What you've implemented is the OAuth Authorization Flow. In this flow, the client (aka the browser) never gets the access token. Only your webserver gets it. And thus the client cannot make calls to the resource server (github). Your webserver makes the calls on the client's behalf.
You say:
a malacious user could interecept the access token when the oAuth provider redirects to the callback either way
However, if you implement the flow correctly, this is not true. This is because once you authenticate with the resource server, it only gives the browser an authentication code. This code is just a temporary ticket that can be exchanged for an access token. However, to exchange a code for the access token, you have to know a client secret. Only your web server knows the secret. So your browser sends the code to your server, and your server calls the resource server (github) with the code + secret to get the token.
The second flow you describe is the OAuth Implicit Flow.
This flow is very much what you described: After the user authenticates with the resource server, the browser ends up with the access token and just calls the resource server directly.
Both flows are very common. The Implicit flow is slightly less secure because there is more opportunity for Bad Guys to get access to the token in the browser's memory (or local storage, or cookie storage). The Authorization Flow is a bit more secure because the token stays on your server, and you do not have to depend upon users to keep it secure.

reactJs secure storage

I'm a back-end developer who has to create the front-end too in the current project!
I'm using reactJs and I know that for authorizing users I should get an api_token from my back-end API then use the api_token in the next requests! so I should store the api_token (actually somewhere into the client's browser)! but where should I store it to be secure?
the first answer came to my mind was 'Local Storage' ! but I've read this article: Don't store tokens in local storage
I've searched and found #auth0/auth0-spa-js, but I don't know can I trust this package (and similar) or not?
these are the way's which I've found! but what's the correct way to store sensitive data like this?
The Auth Flow should be on the Web should be
Send User/Password Details to server
Server validates and returns encrypted token with some details inside and that's stored as a HTTP Cookie
Setup Protected endpoints so only users with token can access them
Security : HTTP Cookie only means that the browser doesn't have access to it on the client, only the server. But someone can simply just Copy Paste it into their cookies which if you're worried about or working on sensitive stuff, you will need to implement additional security measures such as the ones mentioned.
Generally, Device Management is not a web concern but you can also some validation on the token for things like make the token expire in 5 minutes, or expire on session end, DeviceId, Browser Id, IP address, send them an email that a new unknown IP has logged in, etc.
Never store private tokens in your frontend code
You should create a server that can only be accessed from a particular url (the url of your app). This server can have the secret tokens that you need to make calls. The that server can forward requests to the services you will use that need private tokens.

Preserving Authentication over multiple servers

I am writing an application in Google appengine python. Due to the limited support of the appengine environment I have to implement some of the functionality on external dedicated servers. Is there an authentication mechanism available that will preserve login information over the external servers and appengine.
The system you want should probably work something like this:
When a user visits the 'other' server with no session cookie set, the server redirects the user to a special URL on the App Engine app - let's use /authenticate - with a 'next' query string parameter that provides the URL of the next stage (described in #3).
When App Engine receives a request to /authenticate, it checks if the user is signed in there. If they're not, it prompts them to sign in. Then, it generates a token for the user's session, and signs it with an HMAC, using a secret shared by both servers, and redirects the user to the URL provided in step 1, with the HMAC included in the query string.
When the 'other' server receives a request to its special URL (specified in step #1), it validates that the HMAC matches, using the shared secret, and if it does, uses its own session support to set a cookie on the user's browser under its domain, to keep track of the user from then on.
If the 'other' server needs to obtain more information about the user, it can use an API it shares with the App Engine server to request, out-of-band, more information about the user using the token it was given and the shared secret.
This is very similar to the procedure OAuth uses, but entirely noninteractive for the user. It's also the procedure that SSO systems such as Google Accounts use to 'transfer' sessions to other trusted parties.

Resources