2

More of a theoretical question, but I'm really curious!

I have a two part application:

  1. Apache server hosting my UI
  2. Back-end that services all http requests from the UI

The apache service proxies all http requests from the UI to the server. So, if the user is reasonably adept, they can reverse engineer our API by inspecting the calls in the browser's developer tools.

Thus, how do I prevent a user from using the server API directly and instead force them to use the UI?

The server can't determine whether a call came from the UI or not because a user can make a call to myapp.com/apache-proxy/blah/blah/blah from outside of the UI, apache will get the request and forward it to the server, which will have no idea it's not coming from a UI.

The option I see is to inject a header into the request from the UI, that indicates the origin of the request as the UI. This seems ripe for exploitation though.

  • Why do you want to restrict the user from accessing your API directly in the first place? They shouldn't be able to do anything using the API that they can't do in the application. – Pekka Jan 28 '16 at 22:36
  • Completely agreed -- it's a bogus requirement. I think I will get a request to build it though so that eventually the user has to pay for the convenience of an API – honorableruler Jan 29 '16 at 18:15

2 Answers2

3

To me, this is more of a networking question since its something I'd resolve at the network level. If you run your backend application in a private network (or on a public network with firewall rules) you can configure the backend host to only accept communication from your Apache server.

That way the end-user can't connect directly to the API, since its not accessible to the public. Only the allowed Apache server will be able to communicate with the backend API. That way the Apache server acts as an intermediary between the end-user (client side) and the backend API server.

An example diagram from AWS.

enter image description here

Community
  • 1
  • 1
Cyph
  • 623
  • 1
  • 7
  • 25
  • I think you mean to configure the backend server to only accept connections from the Apache server, not the UI, which is running on the client machines. – Remy Lebeau Jan 29 '16 at 05:26
  • Maybe I am misunderstanding your answer, but right now, by design, all client requests from the UI are always proxied through Apache to the backend server via a path param in the url, like "myapp.com/proxy-to-apache/blah". There's really nothing to stop a user from figuring that out and proxying their calls to Apache, in which case, the server won't know where the call originated from. – honorableruler Jan 29 '16 at 18:23
  • Got it, so you literally want to force a user to interact using a web browser. I thought you wanted to ensure the request was funneled through the Apache server, and not bypassed by hitting an exposed API. Maybe we should take a step back. What are you trying to achieve by doing this? – Cyph Jan 29 '16 at 22:07
  • Exactly @Cyph. So, it's a requirement I am getting from the business side. Our app validates stuff and the business doesn't want it to be "too convenient" for the user to submit things to be validated. They are hoping to charge for that convenience. – honorableruler Feb 01 '16 at 15:53
  • 1
    Aside doing something like a captcha or behavioral analysis as "validation" of a user on the other end of the browser I don't know of another way. This is an issue many company encounter when dealing with online fraud. For example, bypassing merchant checkout by doing direct POST of purchase data to automate testing validity of stolen credit card info. So you can either try capthca or a behavioral monitoring script, or have some TOS policy to say you must use the UI and If you are able to detect users bypassing them, you ban them. – Cyph Feb 01 '16 at 18:10
  • Thank you -- I didn't think of things like captcha or behaviorial monitoring but it definitely applies to my use case. TOS is probably the best, however, because even though I can make it difficult for them to hit the API directly, it really is more of a business agreement because the customer and the service provider. – honorableruler Feb 01 '16 at 19:34
1

You could make the backend server require connections to be authenticated before accepting any requests from them. Then make it so only the Apache server can successfully authenticate in a way that end users cannot replicate. For example, by using SSL/TLS between Apache and the backend, where the backend requires client certificates to be used, and then issue Apache a private certificate that the backend will accept. Then end users will not be able to authenticate with the backend directly.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770