8

I'm trying to learn some things about REST apis and one of the topics that I'm having some trouble is security.

I'm using angularjs for web interface ans slim framework for the php api. I've read some articles (I liked this one) and started to implement HMAC following this tutorial (not exactly the same steps). I would like to know if there is some major security breach in my approach or if I'm not doing this the right way.

As I'm using AngularJS, I know that everything I store in the client-side is not safe. I'm assuming that the user has a "clean-as-new" machine and knows what he is doing (I will probably be the major api user). My greater concern is the man-in-the-middle and replication.

(On the client side)

  1. The user inputs his username and password.
  2. His password is encrypted (for example, sha256) and stored as a global; (His username is just stored somewhere)
  3. In every request that the webinterface sends to the api, it is sent a hmac hash in the header in wich the message is formed using the username, a timestamp, the path to the resource, a random string (that both server and client are aware; hardcoded) and the key is the password hash.

(On the server side)

When the server receives the request:

  1. Checks the timestamp;
  2. Checks if the username exists in the DB;
  3. Attempts to replicate the same hmac hash using for the message the variables (also received in the request) username, timestamp, path-to-resource and the random string (this one is not received in the request; it's just hardcoded). For the key he uses the value stored in the DB that is the encrypted password of the given user.

If all validations go well, the user should be a guy to be trusted and not just a man-in-the-middle.

  • 1
    Are you trying to avoid MITM to avoid tampering with messages or to ensure confidentiality? There's nothing here to stop a MITM (or passive attacker) reading traffic. Also, I don't see any value in your "random string". – David Mar 13 '14 at 7:42
  • I am trying to avoid MITM to avoid tampering with messages – Bruno Camarneiro Mar 13 '14 at 9:48
  • 1
    @BrunoCamarneiro - are you using SSL? If not why not? – Hector Jan 16 '18 at 21:36
  • I really haven't a good answer for that. It was 4 years ago. I was just starting to work so I didn't know a lot of things. My boss didn't want to spend money in SSL certificates. Anyway, it was a good exercise and I learned a lot from it. There is no technical answer to your question :) – Bruno Camarneiro Jan 17 '18 at 11:50
6

I see various issues with your approach (in no particular order, and most likely not a complete list):

  • It seems like you're deploying the application without SSL/TLS. If that is the case, you must not rely on the client side, as a MITM can replace your (secure) client-side implementation with anything he/she chooses.

    There is no way to create a secure web application without SSL, as the client would then load your application through an insecure channel. If your application is deployed through a secure channel (not sure if angularjs supports offline deployment), ignore that.

    If you use SSL, that will probably mitigate all other attack scenarios as it protects against MITM and replay attacks. The only thing that could be an issue is Authentication, given you do not use client certificates. But usually session tokens are sufficient for web applications, as the server is properly authentificated (given you use a proper implementation).

  • You wish to secure against replay attacks, but only use timestamps for requests. If an attacker is able to record and reply a request fast enough, the server will consider the request valid. Depending on your actual data this may or may not be a problem.

    To prevent that attack, add a request counter or store the timestamp of the last request on the server (and require a greater timestamp than the stored one).

  • Besides your actual HMAC, you are not salting your passwords, that way an attacker with database access is fatal for your application and your user's passwords. I'd strongly encourage you to salt your passwords.

    Also, it is usual practice to hash passwords many times to increase the workload required for dictionary attacks against the hash.

  • From what you write it is not clear that you include the message/request content into your HMAC. But I assume you are aware of the fact that a HMAC only verifies the integrity of the data it is generated with.

  • You do not use truly random keys for HMACs. Given today's computing power it is likely that weak passwords lead to a crackable HMAC, as possible hashes are easy to compute. Hashing multiple rounds might help a tiny bit (and salting if the attack is against multiple users), but it is crucial you install some brute force prevention at last (maximum number of illegal requests per hour or similar, then block the source IP).

    However, I personally would never trust anything soley based on user passwords.

So, personally, I would recommend against rolling your own crypto and for sticking with SSL/TLS. While that basically means that every client-trusted CA can certify a MITM, I think that that risk is by far lower than a MITM certifying himself by delivering a malicious webapp to the user, replaying requests or cracking the HMAC's secret.

  • "not sure if angularjs supports offline deployment" - its just JS. You can easy enough have a static content folder available to the client machine which all local HTML / JS is server from then this communicates with the server. You could also have an initial empty HTTP page which contains the necessary JS to establish a secure connection over the top of HTTP/80. Although the only use case I can see is 80/HTTP being the only thing allowed through a firewall outside of your control. – Hector Jan 16 '18 at 21:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.