PHP Socket Server (for Android Push Notifications) - Security / Authentication Issue - php

I have recently written a socket server in PHP that will be handling communication between an Android phone application and my PHP webserver. Due to the fact that Android doesn't natively support push style notifications we are going to be using our webserver as the middleware layer to handle our 'pushes'.
The socket server is stable, runs well, and seems to scale nicely. While I would eventually like to re-write this in C I don't have the skill necessary to do that right now so I am going to be staying in PHP for at least a short while. As of this moment our Android emulator is able to communicate through the server, get pushes, etc. so that part is all covered.
My concern is that, right now, anyone can open a socket to my server and will be given a client connection. While we won't be passing sensitive data back and forth I don't want to allow just anyone to connect over and receive broadcast information, eat up my resources, and clog my server in general.
The question is, how do I secure a server like this? Let's assume that I am running on port 25,000--can I set up some sort of SSL layer on that port and expect devices like the Android to be able to communicate over that port without any special protocols or jumping through hoops?
I have considered asking the connecting clients to authenticate their user against our user database before being given a client connection, but that would require the passing of credentials in plain text over the network which I am NOT about to do.
Any suggestions on this would be very helpful--I am rather new to straight TCP communication from PHP and feel like I might just be missing something simple that allows for authentication on this level.
Additional information: If I am able to get a valid username and password securely I would be using MySQL to validate the user and then accept/reject their connection based on the results of the query.
Thanks in advance..

First, I hope you've implemented your PHP socket server in a fashion that allows more than one client to be connected at the same time. This is not as trivial as it should be given the absence of threads in PHP, but it's certainly.
Now, if you already have a socket server implemented, adding TLS support is easy. Just run stunnel and have your PHP socket server only accept requests on the local interface.

I don't think SSL is really going to solve your problem. At best with SSL you can provide each client with a client certificate and do client certificate validation on the server. But you'll need to manage tons of certificates then. Or give everyone the same client certificate (not a good idea).
You'll have to authenticate the client using his credentials. You are right that you don't want to send the credentials in plain text over the network, but there are simple alternatives. Take a look at e.g. HTTP Digest Authentication (http://en.wikipedia.org/wiki/Digest_access_authentication) or xAuth (http://dev.twitter.com/pages/xauth). You don't have to implement these techniques over HTTP; you can just as well send a challenge (a realm) over a simple tcp socket after you have accepted the connection. The client should then send a valid response within a short timeframe or the server aborts the connection.
By the way, did you consider HTTP streaming? See http://ajaxpatterns.org/HTTP_Streaming
It would probably make your life a lot easier as you can rely upon some other service (e.g. Apache) doing the hard work for you, and you can focus on the business value of your application.

you might want to consider:
Cloud to Device Messaging : http://code.google.com/android/c2dm/index.html
The only drawback is that it is only supported by android >=2.2

Not sure why you guys didn't use some off the shelf messaging library/server for java, then create an android service that connects to the message broker and handles all initial authentication.
The service would simply sit there and wait for any incoming messages.
(I'm pretty sure that listening for network data doesn't power up the radio, only when the data is actually there that the radio powers up. I suspect this is how C2DM works.)
This is better then polling because you're only waiting for data. You're not constantly sending packets requesting data. But you knew that already.
I did this, (I used the rabbitmq-java library and the rabbitmq message queue server) and had push style notification for my app in no-time. Even with Android 1.5 devices.
About security:
You could also implement your own security but without having to send plain-text passwords. Simply encrypt the passwords using something like MD5 before passing it through the network.
Then compare the encrypted password with the encrypted password you have on file.
This way, only encrypted passwords will go through the network.

Related

ActiveMQ - any way to disconnect another client based on the client ID?

I am using Amazon MQ which is a managed Active MQ instance. I am connecting over STOMP with PHP using this stomp-php library. I plan on having these listeners running continuously, and if disconnected, reconnect. My concern is that for some reason or another, a script will stop working but the client won't disconnect. If this happens, I wouldn't be able to reconnect with that client ID until the other client disconnects.
If this happens, I want to be able to close the connection remotely. I don't know if this is possible with STOMP though, I don't see anything about it in the STOMP documentation. It seems that once you connect through STOMP, you're connecting as a client and everything you do is in relation to that client.
I looked at the ActiveMQ documentation and I see in Artemis (IDK if AmazonMQ is Artemis or Classic) there's a closeConnectionWithClientID JMSServerControl method. This seems like it's exactly what I want to do, but through STOMP or some other way via PHP.
Does anyone know how I would go about achieving this?
AmazonMQ is based on ActiveMQ "classic" 5.x versions. Via the STOMP client there isn't a way to forcibly disconnect another client, there isn't a way through any of the client protocols as that'd be a horrendous security and usability issue.
To remove a client you need to use the JMX management APIs in 5.x which I'm nut sure are exposed in AmazonMQ instances but that'd be the place to start looking. In 5.x the JMX API can be exposed using Jolokia such that an HTTP request could be used to invoke them once you has established authentication and authorization to the admin role you hopefully have configured.

Direct communication between php script to client (Windows or Android)

I am thinking about a scenario where I want to send a data packet from my php service (based on certain behaviour) to a client (can be Android or Windows) connected to it.
A device which is connected to the internet is going to have an ip address.
So is it possible to send a packet (using socket or else) to this ip directly (without polling from client end) and can this data be read from the client.
Scenario is like this :
Client A --------------Registers Own IP Address-----------------> Server
Client B --------------Registers Own IP Address-----------------> Server
Events :
Some changes occur in the database (say)
Server detects the affected client (via some algo),say Client A
Sends a packet to Client A
Client A <--------------Send Data Packet----------------- Server
Is this at-all possible ?
If yes, how effective can this be ?
Please note that, Push notifications is not applicable in my situation.
I am looking for a live (realtime) data transmission system between client and server (both ways).
Any suggestion, help will be useful. Thanx
Absolutely possible to have persistent sockets open.
but I would say this would fail in a hosted environment. GoDaddy etc shuts that down. Been there done that.
I would highly recommend choosing a programming language like java (Whatever you are comfortable with). It is only going to be 200 lines of code.

How to reverse engineer data from a program sending data to some domain using XML-RPC?

Imagine there is a program which is sending some data to one address call it domain.com to this address it sends some data about food - its qualities and other stuff. How can I reverse engineer these data with the help of the xml-rpc which it is based on?
I need to create some function of catching methots to get hash, login, Seller, listAdvertisement, addAdvertisement, delAdvertisement, Photo etc. I heard there should be some opensource libraries but I did not have any luck finding them or manual how to do this properly in PHP script?
I would strongly recommend using WireShark (https://www.wireshark.org) for taking a trace of network traffic between the program and the web server it is connected to. I use it all the time to monitor traffic in our servers during development; and even in production servers.
It's very handy to look into packets exchanged and supports so many protocols across all layers; not only XML-RPC. It also supports multiple file format for traces taken by other programs. I primarily use it with tcpdump in Linux servers and snoop with Solaris. So, you can take a trace in server and look at the traffic later on using WireShark.
Once you take a trace of traffic, you can look at the XML-RPC payload and get all information needed reverse-engineer the protocol (e.g. operations, parameters and values, expected responses...etc)
I hope this answer helps.
You can use sniffing proxy, eg Fiddler or Charles. It will log all trafic going through.

Making the web server as a relay between two sides

I want to control a robot from the web, the robot is connected to Android device. The operation will be as the following :
a web application written using JavaScript and HTML runs on desktop computer which takes the keyboard input from the user and send them to the android device connected to the robot.
the android device receive the commands and then send them to Arduino board which used to control the robot.
But how should I deliver the data to the Android device which doesn't has a static IP address?
I have two approaches to solve that :
the JavaScript application sends the keyboard input to a web server runs PHP and MySQL , then the php application store the data on the MySQL database. An application runs on Android connected to that web server and extract the data from the MySQL database.
the JavaScript sends the data to the web server. The android application connected to the web server receives the data directly so the web server is just used as a relay.
The first approach is easy to do but its slow , so my question is...
How to implement the second approach and which web technologies should I use to implement it? And how to make the web server works as relay between two sides?
PS : I am planning to use 000webhost.com as web server. so I will not use my own server
You can either have your Android application poll the webserver for outstanding commands. This is a little inefficient in terms of data usage, but if you're on an unlimited 3G plan / wi-fi, you could live with it. It will be very easy to implement.
Alternatively, set up a TCP server on your server, and have your Android application open a socket connection with the server. This way, your web application can send commands to the server which will immediately stream them to the Android device. It will be slightly harder to implement, but will be more efficient and robust if done right.
PS - Most shared servers don't allow you to open a TCP server on your host so you might be forced to go with the first option.
PPS - I wasn't aware of Google Cloud Messaging. It seems to be a good solution for you what you're attempting to achieve. You should have a look into it.

securing connection to php server

I have following scenario:
The Android clients communicate with a PHP server via HTTP Post. The PHP server is communicating with mySQL database and sends the output as JSON to the Android client.
Now I am concerned that people sniffing the traffic, find out the URL and will post a lot of grap in my database.
I have no concern of sniffing the payload. So it does not necessarily be encrypted.
I was thinking of TLS/SSL which comes in mind because of the HTTP connection. But I am not sure what is the prefered way to go in this scenario.
What you want to do is employ mutually-authenticated SSL, so that your server will only accept incoming connections from your app and your app will only communicate with your server.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use the keytool included with the Android SDK for this purpose. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
If someone/something other than your app attempts to connect to your server, the SSL connection will not be created, as the server will reject incoming SSL connections that do not present the client certificate that you have included in your app.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android, both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.
SSL won't help you, as the traffic can be sniffed before the data hits the wire, and people will STILL be able to figure out your API calls and fill the DB with crap.
You can "secure" the service with access tokens and username/password requirements. But again, they won't prevent a malicious user from flooding your system with bad data. However, it would let you track down WHICH user was doing so, as they'd have to be using a unique access token of some sort to get at your system.

Categories