Preventing "Pass the Hash" Attacks in a Web API? - api

I may not be going about this in the best way possible, but as a school project, I'm in a group where we are developing a system to handle checking in and checking out of dorm rooms and handling any charges that may arise because of damages to items in the room. We are digitizing the project and putting in on the web and writing a native iPhone app (part of the assignment, I'd rather just make it a universal web app, but oh well). For the iPhone app, we're putting together a web API but I'm having some doubts about our attempts to keep the API secure.
Our process right now is a call to the API to log in with a username and a password hash, if it was a successful login, an Authentication Token is generated and returned to the iPhone in XML along with various other data. Each subsequent request requires this AuthToken. A user can either sign out, or if there's inactivity for 20 minutes, the AuthToken is destroyed server side. But this leaves the API open for the "Pass The Hash" attack where anybody listening in on the request can get the password hash out of the query string. Anybody with Wireshark and a simple filter can wait for somebody to sign in when everybody would be moving into the dorms and be able to manipulate just about anything.
Every single request is susceptible to the Pass The Hash attack. When logging in, the username and password can be repeated later to obtain a different AuthToken. Not only that, any already generated AuthTokens could be used and the session extended without the real user knowing.
I have thought of the idea of tying the AuthToken to an IP address and rejecting requests that use a valid AuthToken from an alternate IP address, is this reliable or will the iPhone be jumping IP addresses when on the cell network instead of Wifi? I want to give any malicious users a hard time, but obviously not legitimate users.
The project is still in the early stages so now would be the time to make drastic changes to the API like this. Any tips on securing a web API would be awesome.

Your best bet would be to send everything over SSL. That will prevent anyone listening to the wire and sniffing either the password hash or the authentication token.
You should also consider sending a nonce to the client that gets hashed along with the password to prevent replay attacks.
It's also pretty easy to change the authentication token on each request. This prevents both replay and session-fixation. Just make sure the tokens are good random numbers.

You need to use HTTPS.
Most anything on HTTP is susceptible if you include people using Wireshark. HTTPS encrypts all traffic between the client and the server and will prevent most packet sniffing attacks.

Related

What CORS policy to use for iOS and Android apps?

I'm building an API that is meant to be used by iOS/Android apps.
The app uses JSON Web Token to authenticate users.
I ran into CORS issues when trying to talk to the API from the native app.
So I added CORS Headers for ALL Origins (only on urls starting with /api/).
It works fine now, but I'm wondering if what I did is not a potential vulnerability?
Should I allow ALL origins? If the API is going to be requested by native apps, is there a way I can know the Origin host in advance?
I'm quite confused.
Thanks in advance for your help.
The user shouldn't need CORS protection if they have the token. The token is fully identical to the user logging in with their user name and password each and every time you send the token to the server. The threat model that CORS is protecting against is a malicious domain/site, other than your own site, doing an AJAX request to your server using the cookies (including session id) for your domain.
If a malicious domain or entity has your user's token, your user's identity is so PWN'd, that it doesn't really matter what sort of CORS protection you try to do. The malicious domain has the equivalent of your user's username and password. They are completely compromised, until you invalidate their token.
Thus, don't worry about where a request is coming from ( CORS ), when the malicious entity has completely compromised the user's account. Just protect the token as if it were the Queen's jewels. Send it over SSL and store it securely. If the malicious entity gets the keys to Fort Knox, you have bigger problems than where the request is coming from.
Don't Be afraid of let the Cors Origin : * because if you limit server access you may put your business in bad unstable situation so work hard on tokens.
But in my manner I research net and found any encryption have an decryption sometimes as a third party tool and say wow.
Finally Make my own Encryption in 20 days and each day make it harder to decrypt.
Final Answer : understand encryption & decryption then make your functions the way you want and everyone doesn't know.
Don't waste your time for SSL or Internation HASH Algorithms if you want Maximum Security. Afterward you can mix your encryption with International hash algorithms as you like.
Begin from easy character encoding then update and update more , one time you did it you can use in every app you make.
Hope to be helpful.

Securing MY REST API for use with MY IOS APP only

I am designing a REST API in Laravel to be used with my ios app. Currently I am stuck on the following point: How to secure my REST API to allow access to ONLY my ios app?
I have read about HTTP Basic Authentication, HMAC, oAuth2.
1) Basic authentication requires SSL and it requires you to send the username:password on every api call.
But this doesn't stop others from using the API from other applications assuming they post their login credentials to the endpoints?
2) I understand the HMAC method and how the client & server both know of a Public & Private key. The private key is encrypted along with the request and other data. The public key is sent in the headers. When the server receives the request it detects the public key in the headers and associates it with a private key in the DB. It then recalculates the hash and checks if it matches. So, I have the following questions:
How does a newly registered user get the private key to be stored in the IOS app if the private key is not to be sent over the wire?
Is this more geared towards applications that will utilize your app? I normally see this in a API dashboard like Instagram & Facebook where they give you an app secret key, right?
3) oAuth2 - To me this seems more like allowing people to login to my app utilizing another API. For ex, allowing users to login to my app with FB and allowing my API to utilize Facebooks data? I am not really needing to do this at the moment.
am I misunderstanding this?
It sort of sounds like I need to incorporate something similar to the HMAC method by granting my IOS APP a private key where I store this in my IOS APP code. When a request is ran from within the ios app i pass along a hash with the private key and other data and then when the request is received on the server I detect if the request came from a user within the app by recalculating the hash. I have no idea if this is secure & I would assume it isn't?
What knowledge am I lacking? I am so confused at the moment that writing this question was a big struggle. I will revise it as soon as things become more clear.
1.
You're right, this doesn't prevent non-approved clients.
2.
This isn't really a way to prevent unapproved clients, it's more about verifying that a message isn't tampered with over the wire.
3.
You're understanding oAuth correctly, it's about authenticating clients to use your API in a specific way as well as limiting permissions.
It's not really possible to lock down your API so only a specific client can use it, because there's no way to verify who the client really is. Additionally, any form of authentication or verification done on the client side can eventually be be reverse engineered, and then can be sent to the server as an 'approved' client.
Something like this could be done with a token. The server sends a token the the client, the client performs some known operation on the token, such as salting and hashing, with a known salt and hash operation, then returning the token to prove that the client is a real one.
The problem is, if someone reverse engineers your client, they can determine what that operation is, and then create their own client which authenticates the same way. Any form of client side authentication isn't true security and can't be trusted.
Another way this is broken, is if someone can MiTM your request. The request could be captured and modified before it reaches the server, and there's not really any ways to prevent that from happening aside from using SSL, which can be broken with something like SSLStrip.
Any attempt to prevent a non-approved client is basically security through obscurity, since there isn't a provably secure way to do what you're asking.
The best way to protect your API isn't by limiting which clients can access it, but by making it secure already. Best practices would include forcing SSL, only send the password once and use tokens for authentication from then on, etc.

API for mobile app security/auth

I have an API that is serving content to a mobile app, and have no current plans to use the API for other products. I have 2 main questions:
How to prevent someone from sniffing the API requests and making their own requests (this should not be an public API).
If preventing #1 is not possible completely, then how can I limit/throttle requests from un-approved consumers? Are there other concerns here?
Using an auth token (passed as A GET param) for each request satisfies #2 (I can revoke it at anytime) however I do not want to have to update the app to use a different token in future.
Also, there is no authentication for users in the mobile app, and the API is written in PHP.
What are the best practices in this area?
Here are a couple of suggestions that can help keep your API private.
Use TLS to discourage casual packet sniffing.
Make sure your clients verify the server certificate to prevent MITM attacks.
Encrypt or obfuscate the auth token in the client code so it's not obviously exposed in something like a string dump.
Ultimately, though, if someone really wants to access your API, they will - either through reverse engineering your client code, or more complex data interception techniques. The best you can hope for is to discourage access attempts by the average user.
How to prevent someone from sniffing the API requests and making their own requests (this should not be an public API).
I would echo the previous answer that you should use TLS as a matter of course, in order to encrypt the traffic on the wire to prevent sniffing. But I would add that you also need to deter "capture-replay" attacks, whereby an attacker may resend a previous message which they may have obtained (e.g. from a client-side log) despite the usage of TLS. In this case, if you are using a nonce (meaning "number once") and/or timestamp in your requests, with HMAC signing, then the replayed API request can be detected and blocked. I have written about an example of this on my blog: http://www.soatothecloud.com/2011/02/securing-apis.html . Amazon's APIs, for example, use this approach.
If preventing #1 is not possible completely, then how can I
limit/throttle requests from un-approved consumers? Are there other
concerns here?
As well as the HMAC signing (above), you can also consider monitoring incoming IP address range, device info (e.g. headers indicating the device type - Android vs iOS etc), and other factors which can be used to link multiple requests to particular clients, and then apply policies at the API level.
Full disclosure: I work for an API Management / API Gateway vendor (Axway) but the info above should be generic.

Authentication security concerns

I am a beginner web-developer and I have some doubts about the security of an API that I developed. It's a simple web-service that requires authentication in order to access/modify data.
I am wondering what are the best practices for authenticating users via HTTP.
Currently my app works like this:
User authenticates through an API request (POST) which requires the username and the password. The response contains info about the user and a TOKEN which will be used in the future for further requests.
My concerns: I don't know if the auth request should be POST. It sounds more like a GET, because POST should create something (at least this is the convention in Ruby on Rails). And then, even with POST or GET, the information is still "visible" during the transfer of the information. I heard something about HTTPS - how does that solves the problem?
The token is generated at user creation time - and remains the same in time. Is this bad? Should the token be generated again after a "logout"? I've seen APIs that use an API_KEY along a token for authentication. How does that work?
I have some GET requests to retrieve information about something. With this request I pass as an parameter the token retrieved from the authentication request. Is this ok? I mean that token is sensitive information.
Where can I find more information about these concerns of mine (book, article, w/e)?
HTTPs encrypts all traffic to your web site, and so would hide any get and post requests. It requires you to purchase an HTTPS certificate (which are cheap), and get a non-shared IP to host on (not so cheap). (If anyone talks about self signed certificates - well, it's possible, but ill advised if external people want to talk to your service).
Having a long lasting login token can be bad, it depends what sort of non-repudiation you want. If someone can log in 2 years ago, and continue using a token how do you know it's still the original requestor? Tokens should expire and have a way to re-request.
API keys generally work on a shared secret which is swapped out of band (by getting it from the hoster's web site generally). A custom authentication scheme and header is used, and must be calculated and checked for each request. This doesn't require HTTPS - the shared secret is used to generate the authentication header, but isn't sent with it, so the secret doesn't travel with each request. Of course you need to write this code, and figure out what you want the process to be. I'd generally avoid this unless you know what you're doing - you need to take a canonical representation of the request, sign it, then use that as the header. It's not complicated, but it's not simple either.
The problem with GET is more one of physical security than web security - I know that I log into sites regularly at work or at home in the company of others - I certainly don't want my credentials appended to the URL as a query string.
Using HTTPS (SSL) will secure your postdata as the information is encrypted before it is sent over the line. The encryption algortihm uses some quite clever maths in generating its decryption tokens to ensure that it's not susceptible to a man-in-the-middle attack.

Best way to protect a REST service that will be accessed by mobile and desktop applications

I have REST services that I was planning on protecting with Windows Integrated Authentication (NTLM), as it should only be accessible to those internal to the company, and it will end up being on a website that is accessible by the public.
But, then I thought about mobile applications and I realized that Android, for example, won't be able to pass the credentials needed, so now I am stuck on how to protect it.
This is written in WCF 4.0, and my thought was to get the credentials, then determine who the user is and then check if they can use the GET request and see the data.
I don't want to force the user to pass passwords, as this will then be in the IIS log, and so is a security hole.
My present concern is for the GET request, as POST will be handled by the same method I expect.
One solution, which I don't think is a good option, would be to have them log into Sharepoint, then accept only forwarded reqests from Sharepoint.
Another approach would be to put my SSO solution in front of these services, which would then force people to log in if they don't have credentials, so the authentication would be done by SSO, and since the web service directory could be a subdirectory of the main SSO page, then I could decrypt the cookie and get the username that way, but, that would be annoying for the mobile users, which would include the senior management.
So, what is a way to secure a REST service so that it is known whom is making the request so that authorization decisions can be made, and will work for iphones, android and blackberry smartphones.
I have the same problem so let me give you the details and would also appreciate feedback. Since you are using an internal system you have one extra option that I have listed.
My first option isn't perfect, yes it could be hacked but still - better than nothing. With each request you pass the device's unique identifier along with a hash. You generate the hash using a salt embedded in the application along with the id. On the server you match the incoming hash with one you generate at the server, with the passed unique identifier. If someone "roots" their device, and is smart enough they could find the salt - you can obscure it further but ultimately it could be stolen. Also, I keep all requests on SSL to just help hide the process. My "enhancement" to this process is to pass back new salts after each request. New devices get 1 chance to obtain the next salt or get locked out ... not sure about that step yet.
Now another approach, is to have the user enter a "salt" or username and password only an internal user would know - the device obtains a token and then passes it (on SSL) with each request. Nobody outside your company could obtain that so this is probably best. I can't use this since my app is in the app store.
Hope that helps! Let us all know if you ever found a good solution.
My current solution, in order to protect data in the system, is to force people to first log in to the application that the REST services support (our learning management system), as I have written an SSO solution that will write out a cookie with encrypted data.
Then, the REST service will look for that cookie, which disappears when you close the browser, and I don't care if the cookie is expired, I just need the username from it, then I can look in a config file to see if that user is allowed to use that REST service.
This isn't ideal, and what I want to do is redirect through the SSO code, and have it then send the person back to the REST service, but that is not as simple as I hoped.
My SSO code has lots of redirects, and will redirect someone to a spot they pick in the learning management system, I just need to get it to work with the other application.