I upload some data to my server with my application. I send the data to a PHP file on the server and this PHP write the data in my database. This works fine.
But currently I have the link to this PHP unsave in my Android code.
Is there a possibility to save this link or make my PHP only for my app available?
A static key could work but if the key is compromised by an app owner sniffing their own network traffic this protection will quickly break. A cryptographic system should be used instead, for example simple hashing of a secret salt with the time and date.
Both the client and the server should take the date and time to the minute in the same string format, concatenate it with a secret salt, and hash that. As long as the times are in synchrony, it should be fine.
You can also use a challenge-response system. The first request gets a challenge value, and all future requests include hash($challenge.$secretkey) which the server verifies.
More complex but worthwhile is OAuth.
Try to send some secret key as GET parameter to your PHP script.
You can set it on your app and then check it in your PHP script.
Something like this:
script.php?key=893284932890482304
And in your PHP script:
if ($_GET['key'] = '893284932890482304')
{
// do the rest
}
Another option is to set "User-Agent" in your app and then check this information in your PHP script. To be honest, I have no idea how to set "User-Agent" in Android app or iPhone app or whatever you have there, but there is probably some way to do so.
Related
I'm writing an Android app that talks with my php backend server. I want to give sha1 fingerprint to server everytime when i make a request, in this way server will know it's my app and will answer the request. But as you know, apk datas will reverse engineered easly and the sha1 fingerprint can be discovered and can be hardcore written.
How can i really be sure that request comes from my app?
Thanks in advance
edit: to that s.. o. a b.... that dislikes my question. please come here and write why you disliked my question. thanks
You can't really do it as you don't have control over the application nor the network traffic. But here is some tricks :
Put HTTPS in the server so network traffic cannot be spoofed easily with an external app.
Create a HMAC from your server or SSL certificates (need an authority CA) and pass it to the application. Send the HMAC only if you have a specific MAC or PC id or IP address, you can check with files and so on that everything is okay but with reverse engineering, it can be reverted. You can use hash_hmac in PHP.
You should not keep sensitive information in your application but rely on your server-side for all sensitive informations and check.
If you need some data to be kept on the application and sent back afterwards, you can also use PGP keys to sign or encrypt data and then send it back to the sever, verify and/or decrypt it. You can do with GnuPG module or use pass_thru to pass shell args. As the application does not have access to keys, your data cannot be altered nor decrypted.
I have been struggling over the past week to get the ideal configuration for my implementation. Basically, I have a Salesforce Page which makes a REST callout containing some data to be computed, A Heroku server then computes this data before sending the computed data back to SF in the response. This all happens in the background and so no Heroku front end exists.
I want to protect this callout with oAuth2, but I'm not sure the best way to do it:
The data itself is not important, its the access to the heroku app which is.
If I use salesforce for authentication, it means that the callout structure doesn't work (I would have to implement a system for Heroku to grab the data from SF before returning it) which isn't ideal and I can't see a way to use Heroku authentication as it allows access to the api but not the app script in a single structure. I think I have to create my own authentication server within Heroku but I'm not exactly sure if this is the correct way of going about it.
Any tips would be greatly appreciated
This is my callout code from SF:
Http http = new Http();
HttpRequest request = new HttpRequest();
//Sets the url to heroku
request.setEndpoint('My App URL');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json');
//places the content into the body
request.setBody(content);
//Extends the read timeout
request.setTimeout('120000');
//Sends the request and waits for a response
HttpResponse response;
response = http.send(request);
Heroku Side:
post("/", (req, res) -> {
//creates a local var for the JSON string
String data = req.body();
//--** The server then computes this data and calculates output
String computedData = compute(data);
return computedData;
});
I need a way of authenticating this type of connection, Thanks!!!
Did you read the Heroku guide to OAuth? It's pretty helpful. The flow would be:-
Salesforce app issues a redirect to your Heroku - GET https://id.heroku.com/oauth/authorize?client_id={client-id}&response_type=code&scope={scopes}&state={anti-forgery-token}
After user has authorized access there is a callback to your Salesforce app with an exchange token
You Salesforce app then needs to exchange the token for an Access token with your Heroku app with the relevant scopes to access the data at Salesforce
I'm not sure if this is what you want though since the whole point of OAuth is not authentication but authorization ie. the OAuth flow is not designed to identify the user, but to enable you client (Salesforce in this case) to access the user's resources held by the provider (your Heroku app in this case).
Since you want Authentication, not Authorization, there are a couple of approaches you could take depending on how much work you want to put in vs how secure it needs to be (you have to make a call on this).
Quick and dirty but not very secure
You could just check the referrer Header on Heroku and if the client is anything other than your Salesforce app then you return a 403 Forbidden or 401 Unauthorized. It's not very reliable since referrer is not overly reliable but its quick and straightforward if you do not have a great understanding of authentication and just want something quick and basic.
Send a client ID with each request
This could be a Header or be in the body of the request. For it to be secure though you will need to encrypt it since you say you do not want to use SSL/TLS. So you will need to encrypt/decrypt the client ID at each end.
A basic approach is to just use some symmetric key that you share between your client (Salesforce) and provider (Heroku) which you store securely within each app somewhere so that hackers cannot read it. You also share (and securely store) some ID string (ideally some long random hash).
The flow would go like this:-
Salesforce app takes the random ID string and uses the symmetric key to encrypt it. This is what you send in the request to your Heroku app.
Heroku app - on receiving an incoming request - reads the encrypted value. It then uses the symmetric key to decrypt it. Your Heroku app then compares the decrypted value passed in the request and the random ID string (it also has stored locally) and if they are the same you have some degree of confidence that the source of the request was your Salesforce app. If not you deny the request.
Authentication is a big subject, as is encryption. If you really need to protect the data and there is a risk of you being sued if you do not, then you need to do some more research. If the data is not sensitive (or particularly valuable to anyone else) and you are just trying to have some basic front gate which reduces other applications from exerting a load on your application then you could consider just checking the referrer as a first attempt.
I'm developing an Android app which has a service to upload images/files to a FTP server.
To make that possible, the app on the device has to log in into the FTP server before sending data.
And here comes my problem. The user does not need to / have to know about the FTP login data. Only the app itself. I have to store the login data in the Java class. But how should I secure the user and password?
I could encrypt it or obfuscate it. But I think it would be possible for a hacker to read the password at the runtime when the "setPassword(passwordString) methods is called by the JVM:
String passwordString = "myPass";
JSch ssh = new JSch();
session = ssh.getSession(SFTP_USER, HOST_ADDRESS, 22);
session.setPassword(passwordString);
So how could I store my credentials inside the APK file and secure them? I don't want anyone to get access to my FTP server.
how could I store my credentials inside the APK file and secure them? I don't want anyone to get access to my FTP server.
The stated problem cannot be solved.
It does not matter how clever your obfuscation technique is. If you hide fixed credentials in the APK file then someone who analyses your app is going to find them.
If you take only one thing from this answer, let it be that having a single, static password for your server is extremely problematic, as you'll never be able to change the password server-side, because you'd break all the apps. It will be a matter of time before your password is public knowledge and there will be nothing you can do about it.
Any reasonable approach requires separate access credentials for every individual user.
A traditional user sign-up system that involves a confirmation email is a pretty good approach. You can use something like Google+ sign-in or Facebook Connect to minimize the hassle for the end user.
If you absolutely insist on having zero user interaction, an approach that might work (somewhat) is to have the app register for Google Cloud Messaging and then send it a push notification containing access credentials, which the app will store in the KeyChain.
If you generate a unique user ID and password for every app installation, you'll be able to monitor the server and block any abusive access credentials without affecting any of the other users. If you somehow factor the code signing identity of the APK file into the process, you'll have a basic defense against people repackaging your app. This approach will not protect you against an intelligent attacker, but it might raise the bar high enough for your purposes.
Also, regardless what you do, be sure to properly verify your server's SSL certificate. If you don't, an attacker will simply run your connection through a proxy server.
I'm working on a Java application that asks the user for a username & password, and then connects to a server to verify the entered details. If they are valid, it will then ask the server (by requesting a PHP page) for data about that user. The user can modify this information using the application GUI, and changes are sent back to the server.
The main challenge is that the server doesn't use any Java. I need to make the server only use PHP, and it must be able to handle connections from different users simultaneously.
What would be the best way to go about doing this?
EDIT: The application will be requesting multiple different scripts from the server for different types of data, and will need to send and receive quite a bit of data (Probably up to 500 pieces at a time).
Create a PHP file that accepts POST.
In your JAVA, try passing a custom header KEY:VALUE pair that's verified via your PHP file - or try to think of a more elaborate way.
Then, post along the username and password to the PHP file: POST http://server.com/java-auth.php?user=username&pass=password for pseudo example. Then, have that PHP file return a JSON-encoded string or a serialized string... or go super fancy, and encrypt it all with public/private keys.
Hope this helps :)
I've have an application which send request to server side. my concern is that, a hacker could snoop traffic and resend the request after doing some modification in request itself.
I know the best way to solve this problem is to use SSL, but I think that will be an over killer for simple application like my application, I'm thinking to go with simple thing like MD5 algorithm.
This way if hacker tried to modify the request and resent it, at least I will discover that.
my question is that:
do you think this a good a approach, or you think there is a better way?
does the MD5 that is generated on iOS using objective C, will have the same value that is generated in Linux server using Java?
Traditionally you would need to make a hash from your payload + timestamp + secret token. Since only client and server know the token, you should be able to verify the hash correctly. And don't forget to include the timestamp in the transmission!
You may also want to encrypt the whole thing before sending - if the information is sensitive (like passwords, etc).
I believe MD5 will match if made on different systems (if done correctly).