How do I secure REST calls I am making in-app?
Asked Answered
C

3

11

I have an application that has a "private" REST API; I use RESTful URLs when making Ajax calls from my own webpages. However, this is unsecure, and anyone could make those same calls if they knew the URL patterns.

What's the best (or standard) way to secure these calls? Is it worth looking at something like OAuth now if I intend to release an API in the future, or am I mixing two separate strategies together?

I am using Google App Engine for Python and Tipfy.

Chemisorption answered 23/5, 2011 at 0:36 Comment(1)
Thank you, everyone, for your input. I selected OAuth because it is standard, will serve me now, and in the future.Chemisorption
S
6

Definitely take a look at OAuth

It is quickly becoming the "de-facto" standard for securing REST APIs and a lot of big companies are using it, including Google, Twitter and Facebook just to name a few.

For Python on GAE you have two options:

The most straightforward way (IMHO) is using David Larlet's library for OAuth Support in Django available on BitBucket.

But since you're not using Django, maybe you want to take a look at the python-oauth2 library that's available on GitHub, and is considered the most up-to-date and unit-tested implementation of OAuth for Python 2.4+.

Either way I think you'd be much better using OAuth than rolling your own service security solution.

Stratton answered 23/5, 2011 at 1:30 Comment(3)
If you're going to use OAuth, you should probably use OAuth 2.0 wiki.oauth.net/w/page/25236487/OAuth-2 -- github.com/progrium/oauth2-appengineHopper
Why would you use OAuth from your own webpage to your own "private" REST API?Spadefish
@Erick the webpage is the client and the server is the resource provider.Elevator
G
4

Securing a javascript client is nearly impossible; at the server, you have no fool-proof way to differentiate between a human using a web browser and a well-crafted script.

SSL encrypts data over the wire but decrypts at the edges, so that's no help. It prevents man-in-the-middle attacks, but does nothing to verify the legitimacy of the original client.

OAuth is good for securing requests between two servers, but for a Javascript client, it doesn't really help: anyone reading your javascript code can find your consumer key/secret, and then they can forge signed requests.

Some things you can do to mitigate API scraping:

  • Generate short-lived session cookies when someone visits your website. Require a valid session cookie to invoke the REST API.
  • Generate short-lived request tokens and include them in your website HTML; require a valid request token inside each API request.
  • Require users of your website to log in (Google Accounts / OpenID); check auth cookie before handling API requests.
  • Rate-limit API requests. If you see too many requests from one client in a short time frame, block them.
Gillen answered 23/5, 2011 at 14:4 Comment(0)
S
1

OAuth would be overkill in your current scenario (potentially insecure), in that it's designed to authorize a third party service to have access to resources on behave of the user.

Securing AJAX request via an authorized user

AFAICT, you are in control of the client, resources and authentication; so you only need to secure access to the URL's and possibly the communication between client and server via SSL [2].

So, use Tipfy's auth extension to secure your URLs:

from tipfy import RequestHandler, Response
from tipfy.ext.auth import AppEngineAuthMixin, user_required

class MyHandler(RequestHandler, AppEngineAuthMixin):
    @user_required
    def get(self, **kwargs):
        return Response('Only logged in users can see this page.')

Securing AJAX request without an authorized user

If a user is unknown, then one could apply CSRF preventions to help protect the REST service from being called from an "unauthorized" client. Tipfy has this built-in to it's WTForms extension, but it's not AJAX. Instead, the session extension could be used to apply an "authenticity_token" to all calls, that needs to be verified on the server.

Spadefish answered 23/5, 2011 at 0:50 Comment(4)
Thanks, Erick. The only problem is I need to use Ajax even if someone is not logged in. Is there another decorator from Tipfy that fulfills this purpose?Chemisorption
@Wraith, how will identify a valid user from an invalid one?Spadefish
Anyone can use basic features of the site, but some are restricted. Using the decorator is clear-cut when a valid, logged-in user is needed, but I still use Ajax for anonymous users.Chemisorption
The only thing I can think of, is to use the "secret_key" feature in tipfy's session extension to create some sort of hash verification to ensure that the calls are coming from your AJAX app.Spadefish

© 2022 - 2024 — McMap. All rights reserved.