开发者

Securing a web service from "XML Injection"

Currently we have clients that belong many different companies who access our web services. A number of new clients are part of a franchise and want access to company data within the same franchise.

Previously we compared a hash of the company id stored in their authentication credential to the hash of the id of the company they were requesting data for, thus ensuring each company could not request data for another company. However, this method will no longer work as a client may need to access another clients data.

The question is, what is the "best way" to prevent 'XML Injection' (if that's what it is called) where someone could intercept the sent web request and modify the XML with intent to look at a competit开发者_如何转开发ors data.

The only method I've come up with so far is to maintain a server side client hierarchy (e.g. Client A/B/C are part of Franchise A) so we know who is part of which franchise and explicitly check before the data is retrieved.

I've noticed many questions on how to secure web service access, this is not what I'm asking.


You seem to have two problems.

Stopping the HTTP request being intercepted and credentials being used by a third party

The question is, what is the "best way" to prevent 'XML Injection' (if that's what it is called) where someone could intercept the sent web request and modify the XML with intent to look at a competitors data.

This would be a man-in-the-middle attack.

The solution is simple, use encryption by transferring the data over HTTPS instead of plain HTTP.

Stopping one client from accessing the data of another client without permission

The only method I've come up with so far is to maintain a server side client hierarchy (e.g. Client A/B/C are part of Franchise A) so we know who is part of which franchise and explicitly check before the data is retrieved.

This is a different problem, and that is the correct approach to solve it.

Store a list (or other data structure) of which sets of data can be accessed by each user. On each request, compare the requested data combined with the credentials of the accessing user with the access control list.


Don't try to fit an extra layer of complexity over the "broken" credential check you already have. Fix the credential check instead.

What is the problem? The "credential token" you use to check access is the company id (a hash of it, but it doesn't make any difference).

How to fix it? Simply don't use the company id -- use something better instead.

So for example: when someone authenticates against your web service, don't give them an auth token based on their company id. Give them an auth token of (let's create an abstract entity here) an "access domain". Have each company in your database be mapped in a one-to-many relationship to any number of "access domains".

Whenever someone asks for data, see which access domains include that data (e.g. check what domains the company whose data is requested is in). If the credential token authorizes access to any of these domains, go ahead and provide the data.

This is just a basic extension of your current credential infrastructure that will serve your needs while remaining sessionless (I imagine lack of session state is exactly why the system was designed like that in the first place).

Of course note that:

  • This system of access control is not secure against trusted-user attacks. Unless there are other mechanisms in place, what's to stop a customer from brute-forcing the authentication token they send you until it matches the hash of another company id (or access domain) and they get access to that data?
  • As David says, it's also not secure against man-in-the-middle attacks, or even to passive eavesdropping. Follow his advice and use HTTPS to expose your services. This is a no-brainer.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜