-3

BACKGROUND: I'm implementing a PHP Server without HTTPS/SSL. On it, I want to authenticate that the user making calls to server is valid assuming that the communication between the app and the server is being watched by a hijacker (hacker with a network sniffer). I further assume that the hijacker is an app owner trying to figure out how the app communicates with the server in order to hack my system. I will have no control on who is an app owner.

What I have implemented so far is that the app needs to start a session before they can any work against the server. To do this the app first sends a request to the server with a randomly generated code, and an authorization number, and the server responds with a security token. The authorization number is based on the code and some other secret information in the app. On subsequent calls the app regenerates the code and uses the token plus other secret information recalculate an authorization number (it never retransmits the token to the server either). This is how each call is validated.

It's set up so that the calling parameters of one call cannot be reused the next time, so that if a hijacker can see the message used within a session, they cannot do anything with it. Using them simply indicates that the call is "not authorized". I'm 99% sure I've plugged all the related holes to the session communication, such that the hijacker cannot invade my environment.

PROBLEM: The hijacker will see the original session request, reuse those parameters to get a new session and use them to eventually figure out how the session calls the work.

QUESTION: What strategy would you employ to validate that it is only my app talking to the server during the initial session request and not a hijacker impersonating my app in order to start a session?

Note: Saving the session start parameters is unrealistic. One idea I have is to embed the "GMT time + N seconds" into the randomly generated code then test to see if the server's GMT < app's GMT+N; this way the randomly generated code become invalid within N seconds.

Elenesski
  • 409
  • 1
  • 5
  • 17

2 Answers2

2

Rolling your own security system is usually a really bad idea.

The reason HTTPS is so widely used is because it works. Personally, I would suggest buying an SSL certificate instead.

Man-in-the-middle attacks will be executed very easily on this system. Consider if an attacker receives a message from your client, with the newly calculated code that you talk about. What stops them from modifying the rest of the message? The code is still what the server expects, so it will simply serve the request that the client (who is actually the attacker) makes.

Being able to authenticate, verify and disguise information in transit are the key elements in a system like this. Your system doesn't really do any of these.

Luke Joshua Park
  • 9,527
  • 5
  • 27
  • 44
  • Kinda what I needed to hear. Thanks. – Elenesski Jan 09 '16 at 19:56
  • Not a problem. Everyone can create a system that they can't break. Very few can create a system that no one else can break. – Luke Joshua Park Jan 09 '16 at 19:58
  • In researching SSL, I can see how the encryption can prevent a man-in-the-middle from figuring out what the message is, but if the attacker is an app owner I'll assume they can decompile the app. Is there anything I can do to prevent or hinder an impersonation? – Elenesski Jan 09 '16 at 21:03
  • @Elenesski Nope. Not in plaintext. There is literally no way for your server to tell if it is communicating with a legitimate client or someone with malicious intentions. Disguise -> Verify -> Authenticate. The last two steps are useless without the first, because anyone can view the authentication information (username/pass etc.) – Luke Joshua Park Jan 09 '16 at 21:33
  • @Elenesski On a side note, if you implement things correctly, it won't even matter if they can decompile your app. – Luke Joshua Park Jan 09 '16 at 21:34
  • Can you point me to something that explains how to implement things correctly? As near as I can tell, all I need is a HTTPS address and Unity3D (that's the platform) would take care of all the SSL infrastructure. – Elenesski Jan 09 '16 at 23:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/100259/discussion-between-luke-park-and-elenesski). – Luke Joshua Park Jan 09 '16 at 23:42
1

Since your app code can be decompiled, it is quite impossible to have a waterproof solution. However, these approaches could at least protect you from a network sniffer:

  • use SSL with certificate pinning in the app. This will make sure your requests are not readable, even not by a Man in the middle attack. So your API is not exposed.
  • if you insist on not using SSL, you could put a secret key in the app to sign the request, and with the public key of the server encrypt it.
S. Roose
  • 1,398
  • 1
  • 12
  • 27
  • SSL appears to be the way to go. Furthermore, I actually do use a secret key in the app that is the "other information". But as you say, nothing protects me from a user decompiling the app to figure out what that "key" might be. – Elenesski Jan 09 '16 at 21:00
  • Make sure to investigate the certificate **pinning**, this is essential to avoid man-in-the-middle attacks, which can still be done with regular SSL! – S. Roose Jan 10 '16 at 12:18