3

Currently I have the following design:

  • Central cloud hosted server with a REST api
  • Multiple remote servers each with a REST api

enter image description here

Data is posted from the remote servers to the central server at regular intervals.

Commands are issued from the central server to individual remote servers in the form of POSTs to the REST api running on the remote server.

I am worried about security. The most important thing is to prevent unauthorized commands being issued to the remote servers.

Currently I am using token based authentication. Each remote server has a token without expiry issued by the central server that is stored in a config file on the filesystem of the remote server. This token is passed in the Authorization header of the POST requests originating from the remote server.

The other direction of communication works similarly. Each remote server generates a token for the central server that is stored in a relational database in the same network as the central cloud server.

My issues with this design:

  • If the database is compromised, the attacker can issue commands to the remote devices - I am essentially storing passwords in plaintext in the db
  • If the file system of a remote device is compromised, the attacker gets access to the token

What ways can I improve upon this design? The communication from the central cloud server to the remote device does not not need to be a REST api. It seems like what I need is some sort of two-way handshake between the two servers. How is that achievable with a REST api?


Some notes:

  • Both rest apis are served over HTTPS
  • The remote devices often lose internet connectivity for periods of time
  • The remote devices are at risk of being physically stolen

Some things I have considered:

  • I could connect all servers to the central hosted database, and use that for communication. This does not seem ideal because this seems like a security risk to have these remote devices connected directly to the database. Also, the remote servers often lose connectivity.
  • Restrict access to the remote servers to a whitelist of IP addresses including the central remote server
  • Do you have physical control over the server and clients? – pm1391 Feb 7 '18 at 1:46
  • @pm1391 yes to both – Water Malone Feb 7 '18 at 1:48
  • I would suggest you look into OAuth 2.0 or OIDC (oauth.net/2) which is specifically designed to to protect use of APIs. – jwilleke Feb 8 '18 at 9:07
2

Because you are mainly concerned with the security of your program (i.e preventing someone from issuing commands to your clients), you also have to identify your threat model. For example, if you are sending commands to a program to unlock your front door, your approach in designing the application becomes much different than if you are just sending meaningless data such as "hello world!".

Once you have defined that, you can make decisions on whether you should hash a password in your database and lock the key in a safe or a plain text password might work for insignificant data. I will try to speak to your application though without knowing every single detail.

You are already using SSL/TLS so that's a great start. You have implemented a form of authentication, a way for the clients to prove to the server that they are legit. You have physical control over the hosts, so I assume no one can get physical access. If you have static IP's, sure, throw a whitelist in and a possible firewall to restrict certain http methods (GET,POST). You might consider a front end proxy such as Nginx to do all this on the server. I would highly suggest you do not allow the clients clean cut connection to the database. Only allow the server to make connections to the database. You mention you are storing passwords in the database, why not hash/salt them? Again, depends on your threat model.

You mention that the client machines are under your physical access but could be stolen. If a attacker has physical access to a box, all bets are off. Your best bet here would be identifying as quickly as possible that a client is compromised. You are already using tokens, why not have a expiry time

Lastly, any data sent from the clients to your server must, must, must be sanitized and checked. If you have a idea of what the data looks like, set a template and any data received that does not match it, reject it

  • Thanks for your answer. The threat model is different in each direction. I am most concerned with when the "client machines" are acting as the server and receiving actions as POST requests. The threat model here is more in line with the door lock example - they are controlling expensive equipment. – Water Malone Feb 7 '18 at 2:26
  • Both the server and client are automated. Is there a secure way to implement token refreshing in an automated fashion? My only experience is with JWT where token refresh is done by a user entering their username / password. – Water Malone Feb 7 '18 at 2:29
  • Well if the data is that important, I wouldn't recommend exposing a endpoint on a machine that can be physically stolen or accessed. Any mechanisms you put in place can be easily circumvented. But, restricting the clients to only listen to the cloud server can be done with a whitelist and a token of some sort authenticating the cloud server , or whoever is Posting data. Again, I always love the power of reverse proxies to do all this with a simple firewall. – pm1391 Feb 7 '18 at 2:33
  • Tokens are usually stored client side, so it doesn't help your situation much. Here's a nice primer on it. google.com/amp/s/scotch.io/amp/tutorials/… – pm1391 Feb 7 '18 at 2:36
  • 1
    Yeah if you're worry is also the cloud server database, you need to secure the passwords. At some point, something needs to be trusted. Think about what the attacker has to do. Break into machine, get a shell, unlock password to database, discover the password from a hashed/salted string. That's tough – pm1391 Feb 7 '18 at 2:49

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.