Stopping the manipulation of variables used for data collection? - java

I am working on a project in java and I was hoping to be able to collect statistics from the client and a possible problem that I fear will occur is the manipulation of the variables used for collection which will lead to illegitimate statistics. Is it in any way possible to prevent the manipulation of variables or is it always possible?
For example: I want to log the actions made per hour from the client. The variable acting as a counter for the amount of actions performed is manipulated and a much larger amount is added to the counter. This data is then uploaded to the server (Of course using a multi-tier architecture to prevent even more possible problems) and considered 'legit.'
Is there any way to prevent this?

Depending on how the data is uploaded, there are various ways to secure the information.
If you are uploading some kind of text or data file, using basic encryption, even a ZIP with a password, should be sufficient to stop casual users from changing the information.
Your application could also simply use RMI or a web service to upload the information, never giving the user the change to manipulate the data.
All of this of course assumes that the application itself gathers the information - if users have the opportunity to enter the data, there's no real way of preventing them from giving you bogus information.
Without knowing if this is a desktop or web application, I'm going to suggest you encrypt your upload files somehow. It doesn't have to be complicated, just enough so someone can't edit it in a text editor.
Just remember that if something runs on the client machine, it can be manipulated. Java is not a secure language, nothing is, for that matter, and while you can do many things to secure applications, there's always someone just a little smarter out there that can crack it.

If I was doing this, I'd do the accumulation of the statistics on a secured machine. Have the primary data gathering code send "event" message to the accumulator, and have the accumulator keep a log of the raw events and their arrival timestamps. This won't prevent people manipulating the stats, but it could make it easier to detect suspicious patterns after the fact.
Building on that idea, you could arrange that event generator application (on the user's computer) uses some kind of handshaking involving a shared secret or public/private key encryption. I don't think you can fully secure this, but security-by-obscurity could be enough to deal with attempts to cheat by people without the skills to reverse engineer the code.
But like Ewald says, any algorithmic process can be reverse engineered by someone who has sufficient control of the hardware it runs on. If the process needs to use a "secret" to operate, then that secret can be revealed.

Related

Android: access internal storage from another app with same signature

Context: I have two apps, both signed with the same signature. The first app has data stored in internal storage that I would like to migrate to the second app.
Question: How can I access the data in the first app from the second app? The Android documentation makes reference to "signature permissions" (https://developer.android.com/guide/topics/permissions/overview#signature and https://developer.android.com/training/articles/security-tips#StoringData) and hints that it is possible to share data between apps with the same signature, but I cannot find clear guidelines about how to do this.
It seems like it might be possible by creating a content provider? Or is it possible to directly access the files, since I understand from the docs that they will be running with the same user / same process?
Ideally this process can happen with minimal intervention from the user, and can all happen from the second app (e.g. the second app can recognize that the first app is installed, prompt the user to migrate, and then read the data from the first app and move it to the second). It would be even better if it was possible to move the files (rather than copy) because we potentially have a lot of data and the user may not have enough disk space to copy the data.
It seems like it might be possible by creating a content provider?
Yes. You can create a signature-level permission and use that to protect access to any of the standard IPC options in Android, including ContentProvider and Service.
Or is it possible to directly access the files, since I understand from the docs that they will be running with the same user / same process?
No, two apps signed by the same signing key to not run as the same user, let alone in the same process. android:sharedUserId has the apps run as the same user. This was never a great idea, is deprecated, and is likely to go away soon.
It would be even better if it was possible to move the files (rather than copy) because we potentially have a lot of data and the user may not have enough disk space to copy the data.
That suggests that having two apps is a bug, not a feature, from the standpoint of the user. The closest you will be able to do to a "move" operation is "delete-after-copy", so plan your copies to be as granular as possible so you can delete as you go.

How to "hide" sensitive system properties like passwords set by Java applications?

I am maintaining an existing Java product (which has a HUGE code-base). I discovered that it is setting (and getting) two of its internal passwords as Java system properties, at no less than 4-5 different places (methods). Now, the problem is, the passwords are being stored as plain text in the Java system properties, and so, the same is visible to external entities, as the application is not using any Java Security Manager. For example, if the application (process) is running on port number 1234, we can run the Java command:
jinfo -sysprops 1234
to view both the passwords as values of the corresponding Java system properties. I wish to ask if there is any remedy to this without changing the existing code-base too much? The desired effect would be to "hide" the two Java system properties (denoting the two passwords) from all external entities.
It may be noted that introducing a Java Security Manager into the application may not be a solution, as if we revoke read permissions from the said two Java system properties using the Java Security Manager, the application codes which read those properties would crash. Same is applicable for storing the passwords in encrypted form, as that would crash all codes within the application which are expecting to read the passwords in clear text form.
Since you said:
...at no less than 4-5 different places...
and you really don't want to do major code changes, I would:
Supply the password in an encrypted form.
Go through those 4-5 places (it's not so much!), and call a wrapper method that you have to write separately: MyPassUtil.getXYZPassword() which internally calls the System.getProperty() to get the encrypted password, decrypt it, and return the plain text version to whoever is calling it.
Keep in mind though, that this way, the decryption key and algorithm is stored within the application, and a good Java decompiler (JD-GUI or CFR) will still return this information. In other words, anyone with the access to the JAR file, can still get the information with some minor effort, something which I presume, since one can call jinfo, they can also get the JAR file.
The best is to use some form of keystore, which again, you can easily implement once you do the wrapper method mentioned in step 2, without affecting whoever is using it.
Also, some security tips:
If it's an SSH / SFTP connection, set up SSH keys between the two machines, and eliminate use of passwords.
If it's a database connection, at least configure the DBMS to allow connections only from this particular machine's IP address. If the connection is over the internet and you are behind an NAT, set-up a VPN first, and channel the traffic between the hosts through it.
For other setups, try and see whether there are some other tips you can do similar to these two points, to improve the security around these passwords.

Keep password in memory

I'm currently working on a project in which I need to keep the user's files encrypted. This part I've achieved easily by using Java's built-in cryptography library. Loading the file from the disk is done by reading the salt from an attached file, having the user input the password, and then generating the salted and hashed key, which is then quickly disposed. But when it comes to saving the files back to the disk, a problem arises because I need to keep the key in memory throughout the whole runtime, or have the user input the password every time I write the file to the disk. What would you recommend in order to keep my application as secure as possible.
To be as secure as possible then your user should enter the password again. However really you need to look at the use-case and decide what you are defending against.
For example if they have to enter the password again then they are more vulnerably to someone shoulder surfing or key loggers, etc but the increased risk is pretty small.
The password kept in memory is only vulnerable to processes already running on the machine the software is running on. That again is a pretty small risk as it would probably be easier just for them to put a key logger on.
So really in this sort of scenario the main risk factors are the people. Can someone trick the person entering the password into revealing it (i.e. spear fishing, fake login prompts, key loggers, shoulder surfing). Mitigating most of those risks is about training, not about technical issues at all.
Far too many people think that a technical silver bullet can solve all their security woes. It really can't, a system is only as secure as its weakest link and you need to think about the big picture as well as the small one.

Java Encrypting logs

I am currently making a game. I have build logging facilities internally, and there are message types like general, log, exception, send, receive, debug.
The send and receive logs contain the raw logging information, so they really contain what I send over the network.
The game uses a client-server model and uses a SSL connection such that the network information cannot be altered. However for the logging I would be logging the text as plain text, and that obviously will cause trouble. Also I plan on simply masking (by *'s) any personal information (like passwords, etc.)
However I have a few concerns:
The client program contains the truststore to use with SSL and the server's hostname/IP and port are not really a secret either. So if a person knows what to send over the network, then he can act like he is the client, right?
If a person can see what the client sends and receives, then he might be able to make a bot very easily. (The game is a turn based 2D game, so by simply relying on all network data you should be able to play the game I think. There is no skill with the mouse required in any way.)
So all in all: How can I still log all information and write it to a file, but without anyone else being able to read, modify it or use it in any way?
All comments are greatly appreciated, and I would also appreciate concrete suggestions as how to implement such a system.
Regards.
If you're worried about encrypting data on your server, then the easiest solution is a whole-partition encryption program like Truecrypt - this will protect the server data if somebody steals the machine / hard drive.
If you're encrypting data on the client's machine, then this means that the encryption key must also be somewhere on the client's machine (even if it's in main memory). Go ahead and encrypt or obfuscate the log information to make it more difficult for users to read it, but be aware that a user will still be able to read it if (s)he puts enough effort into it. That said, the best way to obfuscate the data is to encrypt it with a key that is never saved to disk - for example, when a user logs in then send them a fresh encryption key that their client app will use to encrypt log data; on your server, keep a record of what keys you've sent to the client and at what UTC timestamp. Store the logs with an unencrypted timestamp, so that when the user's client app sends log data you'll know which key to use to decrypt it. Obviously the user can easily change the timestamp, but this is equivalent to the user simply deleting the log data from their machine (which you can't prevent); meanwhile it is fairly difficult for the user to figure out what key was used to encrypt the data, so it's not easy for the user to read or forge log data (but again, the user CAN read / forge log data if they put enough effort into it).
You can take steps to obfuscate the encryption key in memory by e.g. storing it in multiple pieces. For example, assuming you're using AES 128, you can store the key in two 64-bit chunks that you concatenate before encrypting data, then wiping the concatenated key from memory as soon as you're done with it. Or you can store two 128-bit keys that are Xor'd together, again wiping the Xor'd key from memory as soon as you're done with it. A dedicated user can still figure out the key, but this will make it a bit more difficult for them.
Another step you can take is to use an encryption algorithm besides AES, e.g. any of the other AES finalists like Twofish or Serpent (don't implement your own encryption algorithm, you're better off broadcasting that you're using a strong algorithm like AES than you are using a weak obfuscated algorithm). Just remember to obfuscate the encryption library's class and method names to make it more difficult for the user to figure out what encryption algorithm you're using. (This is much more effective if you're compiling to machine code - it's probably not worth it if you're using Java, because the user can simply decompile your code and use your own decryption code to decrypt the log files.)
In terms of figuring out if a player is a human or a bot, not even games with much greater budgets than yours are able to reliably do this - all you can really do is boot the user or send them some sort of captcha if they exhibit "bot-like" behavior, but this isn't fool-proof, and you really ought to favor not annoying legitimate users over booting bots.
There's not much you can do. If the client is written in Java it is pretty easy to reverse engineer, or to use something like AspectJ to monitor what the client is writing to the network. Likewise for any data that is written to a logging system, even if it is ultimately encrypted.
I have the exact same need as you. Some guy called 'maybeWeCouldStealAVa' has written a great implementation in: How to append to AES encrypted file
I've confirmed that it works, however when I 'flush()' at the end of each line, I'm missing the last part of the message - up to 16 bytes - until the next message is written. I could close() at the end of each line, because this seems to be the only way to write the padding. But at least it doesn't need to read the whole file in order to be able to append to it.

Is JApplet Writing safe?

So I am creating a JApplet Game, and I am saving the users info to a .txt file in the APPDATA. Is there a safer way to save their info, that won't allow them to edit it to cheat?
Basically, the only way to prevent cheating is to have a server under your control calculate the score and otherwise enforce game rules. If you were writing a peer-to-peer game, there might be some protocol to allow users to determine if another player was cheating without involving you. ACM sigecom regularly publishes research about such protocols. However, because of the restrictions of the applet security model, users would need to grant your applet special permission for it to talk directly to other users anyway.
Speaking of that, I would advise against "saving the user's info to a .txt file". %APPDATA% is Windows-only, thus breaking "write once run anywhere"; and the default applet sandbox does not allow reading or writing local files, so you'd have to sign the applet and convince your users that it was special enough to merit such elevated privileges.
However, you do have a few options for applet/server communication:
REST calls using java.net.URL
SOAP calls (there are several libraries for this)
RMI (only if the server is written in Java)
Your own custom protocol over TCP
Applets can't read and write cookies directly, but JavaScript can, and JavaScript can call methods on applets. One last way to pass information from the server to the applet (but not back out) is through PARAM tags. You could even pass initial game-state data signed by the server's private key and base64 encoded in a PARAM tag; which would prevent anyone from "editing" it, although I can't think of any way to completely prevent cheating if something about the game-state is supposed to be hidden from the player but known within the applet code.

Categories