How to secure a web service without logging in

I have a mobile application (currently iOS and soon Android) that talks about a web service. No login and data is not private. Basically, the POST application sets the marker (lon, lat) and the GET contains the next 25 markers to be displayed on the map.

This is a very trivial application, and I cannot imagine anyone making a big effort to abuse a web service. However, I see that for someone there is interest in posting many markers. What bothers me the most is that someone is running a script that pushes many requests (using expensive bandwidth and making meaningless data in my application).

I slowly conclude that this is not possible. The best answer is don't do it. Do not provide a web service without authentication. Not many services are open. The Google You Tube API is open, but most are not. Unfortunately, I have no choice. Therefore, after several days of looking at it, here is my thinking. Keep in mind that I am very far from a security expert, and I am sure that my approach can be improved. But that may point you in the right direction. Hope someone more experienced can call back and fix / improve this. I found this article and the comments are especially helpful.

Message Level Security

I will protect msgs with hash encryption. Clients and the web service keep a copy of the shared secret, which is used as a salt to create a hash from the URL and all POST arguments. The hash is passed as an optional argument, and the hash is rebuilt and compared at the other end (using the shared key as a salt). This is very good until you understand that any mobile client code can be programmed in reverse order in minutes. At this moment, this line of defense is completely useless.

Customer measures

The client includes message rate limiting as a measure to limit the number of messages sent by honest users. And yet it is useless against an attacker who jailbreak a mobile device.

Server side security

Thus, the server side should have as many additional security measures as possible in order to be independent, based on the assumption that your client (and the shared secret) are compromised. Here is what I have:

One msg arg is UTC time, which is used to limit replay attacks. This should prevent the attacker from restarting the same msg on the server.

The server performs IP rate limiting. Yes, IPs are easy to fake, and switching between proxies is a game for children, but it helps when you have so little.

Of course, the server strictly checks all arguments, uses parameterized queries and does not return an exception.

Transport Security

Unfortunately, I am sure that issuing certificates for individual SSL clients is not possible without registration. And since I use the msg hash check (and my data is not private), I'm not quite sure what SSL brings to the table. However, I will probably use SSL (with one application certificate) because it adds another layer of security that is easy and cheap to deploy (albeit at the expense of additional connection time for each message).

The Gaping A big big hole in my approach

I warn that if the application becomes popular, someone will compromise the shared secret on the client. Just because they can, and they are likely to post it online. So it really comes down to the server side. Unfortunately, I do not have the ability to identify and block the attacker. I would love that very much.

Final request

After several days of research, that’s all I have. But I want more. I would especially appreciate any ideas aimed at reinforcing the server side. So, I put all my EXACT POINTS as generosity. Yes sir, all 97 points!

+48
security ios web-services
Aug 12 '12 at 15:05
source share
8 answers

In fact, in your particular case, since this application is currently only for iOS, there is a solution.

  • After the user downloads and launches the application for the first time, the application enters the API /access_token/create , which contains the GUID and transfers it back to the application via Apple Push Notifications.

  • App stores this access_token and uses it in all subsequent requests. Your actual API can evaluate the limit based on access_token.

Basically, you let Apple do all the hard work of ensuring that the original request comes from a real iOS device.

Extending this to desktop clients is possible, but somewhat disrupts UX. Just change step 1 to allow /access_token/create to accept arbitrary requests, and if the request does not belong to the iOS device, make the user check their email address / resolve captcha, etc., before giving them access_token.

Android devices (not very familiar with them) may have a similar Push Notification mechanism, in which case you can use this or not have a Push Notification mechanism, in which case you can expose Android users to the inconvenience listed above.

+21
Aug 22 '12 at 19:30
source share

I heard about this idea once when I talked about finding a global solution to the SPAM problem: it made your client do some time calculations.

To be precise: find some computational algorithm that can calculate some z for a pair of x and y in no time, but it takes quite a lot of time to calculate z , only x is given. I can’t provide the actual algorithm, but I’m sure there are a lot of them, whatever that means.

Now the whole procedure should look like this:

  • At the first request of the client, some session_id is generated and for this session_id pair of x and y .
  • Provide the client with session_id and x .
  • A client can run calculations as soon as it receives data (in some background thread that is not related to user interactions).
  • To request tokens, the client must provide session_id and calculated z .
  • You can quickly check if client z is suitable, since you already have x and y that allow you to do this easily.
  • (option 1) For each session_id store how many / often it is requested. At the moment when you suspect that he is being abused - force regenerate x and y .
  • (option 2) Configure new x and y for each consecutive request for session_id .

The choice between 6 and 7 is actually customizable, depending on the complexity of the algorithm and the expected “fair” use of the marker database. If your grades are good, an evil client should never receive too much data or overload your server.

Hope this helps.

+12
Aug 17 '12 at 16:32
source share

In fact, you cannot do anything on the client side. You must provide your client with the entire application (including any keys or any other security mechanism). If an attacker wants to play harm with your web service, he will have to do some reverse engineering to get to your web service. You can make it harder, but you cannot prevent it, no matter how hard you try.

Id just implements speed limits on the server side (by IP address) and no longer worry about it. This is a battle you cannot defeat. If someone really wants to damage your server, they can simply use DDOS without knowing anything about your web service protocol.

In addition, generating a unique key or certificate for each user automatically at the first connection does not help at all. After the attacker reconstructed your protocol, he knows how to deal with all this and should not play by your rules. Nothing would stop him from asking for a new key from your server every time he encounters a speed limit.

A signed Kuba Wyrostek approach can work - getting the client to do some time-consuming calculations that you can quickly check before allowing the request to be processed. But it may not take too much time, or your users will complain about reduced battery life. Also, an attacker is likely to use more powerful desktop equipment instead of another iPhone.

And the last moment - do you really think this is necessary? You do not want your users to register, so your data or services may not be too important. So, what should someone get from reverse engineering your application and flooding your server with requests?

+5
Aug 19 2018-12-12T00:
source share

I really looked for a reason to implement some of these ideas. The big question and answers so far.

I agree with @Kuba Wyrostek regarding its consideration, since the spam problem is part of the solution. Especially if your application has text messages (adding a store, service or message), you may find that the usual cause of spam in your application would be to advertise something. This will lead to my first recommendation:

1) Consider each message reliability as a percentage of 0% to 100% valid . Design a server-side process using heuristics to mark a message more or less reliable. This will allow you to target some additional methods (for example, get the client to calculate a complex value) only for those queries where it is necessary. You can also easily register and view possible abuse (and more easily clear this abuse after targeting it).

Your applications do have an advantage over email servers in spam warfare, however - you control both sides of the conversation. This situation actually reminds me of two other situations that may come in handy: Pay-TV satellites “wars” and Instant Messenger clone “wars”. (Jeff Atwoods link to Black Sunday hack , for example). Here are a few ideas from those confrontations that can help you get ahead of the cat and mouse game a bit:

2) Require the client to send additional data - the same amount of data about the request makes sense. On iOS, submit accuracy metrics for the location. On Android, you can get raw GPS data such as ephemeris information. Then you can (maybe not immediately, but later), start checking this data for validity. This makes someone redo job requests a lot harder. For example, if they send GPS satellites, you can check this based on well-known data for confirmation.

3) Force your opponent to a mobile device. . As @Sven notes, your attacker could use a desktop PC, which means that the request is “computationally expensive” can become trivial. Do not let them do this (or at least make them work harder). For example, you can calculate some mathematical function (sent by the server) and see, based on the phone model, if it returns the correct number of milliseconds. Or do a small 3D rendering task with data from a server that relies on hardware clipping behavior. Hash the result and send it back. All of them will be within the range - this is a multi-tasking OS. But it will help a lot.

4) Go to them dynamically . Send the bit of the algorithm to be computed in the client context. Apple gets a little ridiculous in terms of remote code for interpretation, but something like sending a bit of javascript that is not displayed to the user may work. This code can ask all sorts of unique questions (screen resolution, browser version, WebKit quirks) that would be hard to foresee. As they catch up with you, you can become more creative with them.

5) CAPTCHA . If your heuristic starts to see suspicious data, force it to authenticate. If you have a multilingual application, it can be as simple as matching an image or Unicode character with another. Change it so that it can be updated later.

In any case, a few additional ideas. Good luck

+3
Aug 19 '12 at 23:37
source share

The easiest way to implement speed limits on the server side is to simply use the web server plugin / module. For example, if your service runs on apache, install and configure mod_evasive. This will allow you to estimate the limit based on IP address, service / URL, etc. Mod Evasive will be more efficient than what you can implement yourself.

If you use keys, you must have some way based on the "captcha" method, so that the client can receive the keys during registration. You could cancel accounts for users with violations. Correctly, of course, one of the parameters will be a timestamp, which will be checked both last and in the past on the server side. The key will encrypt the entire payload along with the timestamp and be added as an additional parameter. Storing the frequency of requests on a per-key basis ends with some sort of consolidated database being required, unless you check the repetition of the last request.

No client-side speed limit will make any difference. Someone may discover your API on the Internet without even seeing their client. I doubt the shared secret will be effective for long.

You will find many web services that do not require a password and are simply limited in speed ... for example, the twitter API offers many API services without authentication with a speed limit.

+2
Aug 21 2018-12-12T00:
source share

Here is another “solution”:

  • Do not waste time on this problem.

because:

  • you do not open the public interface to the world, so you can change your web interface at any time through updating the web service and updating your application.
  • the application is "very trivial" (as you called it) and is probably underutilized now.
  • you probably have the best things to do right now, and they just take time.

if there is suspicious performance or query spikes for the least time-consuming solution:

  • enter the password (clientid) stored in your application (blocks 95% of these users), this client can subsequently be used to identify different clients if other programmers want to get legal access to your service.
  • introduce a speed limit (as indicated above)

it will solve your problems in 99.99% and you can work right now and write amazing new features.

+2
Aug 23 '12 at 8:12
source share

It's complicated, you don’t expect anyone to change the data ... so your concern is not about integrity. And since you do not maintain a list of clients ... there can be no concern about authenticity?

And for all of the well-known Webservice attacks (like DoS or replay attacks), you get firewalls that can prevent them. Therefore, I do not think that you need to worry very much about them.

But then you do not want to send text data and want to make sure that your download application is what pushes the data.

If you look at the approaches you are evaluating:

Protected key . As far as I understand, the server and the application will use the same key, and if I'm right, all applications on all devices will use the same key. And when the application pops the data, it hashes the “Actual feed” and sends it through the “Actual channel + hashed channel”. On the server side, you will use the key and hash of the actual feed and check if it matches the hashed feed. And, in my opinion, this decision mainly concerns the aspect of data integrity, which is not a serious problem for you. RGT! (And yes, it will probably be easy to reverse engineer.)

In the above approaches, the server will need to store the So key, if your key is compromised, your entire service will be, and it will be difficult to update all applications using the new key. Or, if the application generates a key, it will have to send the key to the wire along with the message as a digest or something (for example, a timestamp + random number). Not so hard to break.

Certificate: Even with certificates you get the same security .. but it’s hard to break, but easy to steel :). If you save the private key with the device (of course, you will have to maintain the public key on the server). You will have to assign a private key for each client, and then the server needs to maintain a public key for all assigned private keys. If the private key is compromised, only one application can be red and requested to be updated.

So, what remains of the application development perspective, you want to avoid fabricated data. For the sake of harm prevention The only thing to check for such things is the application logic. You will need to cache the last ten (or even the optimal number) feeds (coming from the same IP address) and have some logic, checking to see if there is a flaw.

+1
Aug 12 '12 at 16:30
source share

You can use the speed limit + client "soft" registration.

Basically, you should generate a device identifier that you could save in the user’s settings on first request. For each request, you track how many requests were sent to the server and limited by its server side. This can be done very quickly.

You may also have some kind of shared secret used to sign your request with the generated device id + post / get parameters

+1
Aug 17 '12 at 17:17
source share



All Articles