Encrypting data in a Firefox add-on - perl

I am using the request module in the Firefox Add-on SDK to access my Perl application. In the Firefox panel the user will enter his name and password which is relayed to my Perl CGI application.
Firstly, I would like to know if this is a safe approach.
Secondly, is there any chance of encrypting the data and then decrypting it again on the server side (written in Perl using the CGI module)?

Firstly, I would like to know if this is a safe approach.
As far as the client-side goes - depends on how you store this password. If you remember the password rather than requiring the user to enter it again each time then you should use Login Manager for that (which stores it encrypted if the user defined a master password). When using Add-on SDK you will need chrome authority for that:
var {Cc, Ci, components} = require("chrome");
You can then replace Components.classes in the examples by Cc, Components.interfaces by Ci and Components.Constructor by components.Constructor and these code snippets should work correctly in your extension.
Secondly, is there any chance of encrypting the data and then decrypting it again on the server side
If your goal is to protect against eavesdropping then you do not want to use symmetrical encryption - it uses the same key for encryption and decryption and the key used for encryption will be visible to anybody looking at the source code of your extension. So you want to use an asymmetric (public-key) encryption algorithm like RSA. However, using it "manually" in Firefox is currently very complicated and involves accessing the NSS library via js-ctypes (DOMCrypt extension does it this way). Not to mention that you would still have to think about replay attacks and such. The much simpler solution would be using an HTTPS connection to communicate with the server.

Related

How to encrypt config file in a Perl Dancer application?

I have some sensitive information (my database username/password and cookie encryption key) in my config file for my Dancer application that I would rather not be shown as plain text in case someone does gain access to it. What's the best way to encrypt the file so it's not just text? Or is there a more secure approach that makes more sense than encryption (like restricting file permissions)?
Because you can't encrypt the config, as in the comment above says #ThisSuitIsBlackNot, but sometmes is good to hide passwords (e.g. hide the passowrds form some co-workers who doesn't knows perl - but has access to config files)
I'm using an combination of
security by obscurity
and fooling
In my config files are passwords in encrypted form, and looks like as instructions for configuration. If someone grabs/reads only the config file - get nothing usable.
Usually I'm using something like the next:
db.password: enter some safe password here such De4w.Quafy3yq
and in the code i exracting the "De4w.Quafy3yq" part and using rot13 or crypt etc... get the real passwd: "Qr4j.Dhnsl3ld". Or using the mh5 hash of a string as a password, or similar - simple algorithms.
It is simple, and effective against non-programmers - of course, isn't helps when someone knows perl and grabs the code too.
EDIT
Because seems (downvotes) than here are still some people who didn't understand what this mean, THIS ISN'T ANY REAL SECURITY. It is an nice (funny) method (of course unsecure - read again, it isn't mean any real security) how to hide the password form coworkers, who didn't knows perl. DON'T USE IT for any real password protection. OMG...

client-server game secure architecture

I am currently designing a distributed iOs game. It must contains kind of an authentication (username, password pair I think but please give me other idea if you have). I plan to do it through a simple RESTful API coded in Perl.
I know it is kind of a classic problems. I've seen lots of posts on the web talking about how to do this securely. However, too much informations kill its informative goal. So, I am a bit lost. Nevertheless, I've tried to outpoint the basics concepts, namely:
use SSL (so use https url), it allows you not to think about encryption
use embedded private keys shared between the server and the client, but how to embed them is the question! It allows to use HMAC and to do kind of an authentication.
forget about absolute security (because you use security by obscurity): if anyone can destroy your security by decompiling your app, you gonna have problems !
Here are the questions:
how to share private keys ?
what to send to the server ? username/password encrypted ? some api key ?
do I have the right approach (securing a personal restful api) ?
Thanks !
First of all, it's quite broad question. So it may get closed because of this.
Trying to break down your questions to sub-questions/sub-notes
1) First and most important, as you pointed out. There is no absolute security. You should defined what is valuable (what are you trying to protect) and against who are you trying to protect:
unauthorized user
unauthorized user with inner knowledge of your app (reverse engineered)
authorized user with inner knowledge of your app (reverse engineered)
1) https is "the must". As you figured it out, you don't have to worry about privacy and integrity.
2) In most cases, an app should send username and plain password. This password should be hashed by the server (don't forget to add some salt to it) and compare to stored hashes in your DB.
3) I don't think that you need to share any private keys between client and servers for several reasons:
SSL ensures privacy (so no one can eavesdrop)
Encryption of any parameters using shared secret key which is hardcoded doesn't help too much (it could be reverse engineered and extracted from your app)

REST(ful) simple authentication without SSL and HMAC?

I wonder if it is possible to have an easy authentication method that is restful, fast and provides a litte security.
SSL is not an option, because I can't rely on a valid SSL Certificate on the server of clients. Also HMAC is not really possible because the body of the request should be signed, when used properly, but in my case that body could be a large file. Further should the authentication be possible with JavaScript/AJAX.
I thought about something really simple. What's the problem with that one:
HEADER: X-Authentication: timestamp:username:sha256(timestamp:password)
The server knows the users password and could check the hash, the timestamp is used to only allow request that took place e.g. 10 seconds before. The replay window would be extremly small, and there are no sessions on the serverside.
If the hash is cracked the attacker knows the password and has unlimited access.
Alternative would be to use
HEADER: X-Authentication: timestamp:username:HMAC(password, 'timestamp+request-method+verb')
What's the way to go? I'm not a security pro, maybe storing the session on the server would be better (but not RESTful)?
I built a random hash algorithm that does what you need, it's called jAuthenticate.
You can download it from: https://github.com/thomasoeser/jAuthenticate​
You can see how it works here: http://furiousgryphon.com/jauthenticatedemo.html
The reason it's a strong algorithm (in my opinion) is that I'm using a random number to influence the hash but I'm sending an obfuscated number with the hash.
Each hash is single use only.
Have a look, it's free open source (MIT).
HTTP authentication is extensible so you can invent your own mechanism (obviously at your own risk!). See https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p7-auth-20 for details.
Don't bother inventing your own new X- header. Using the existing Authorization header with your scheme is a better option.
e.g.
Authorization: kruemel-auth timestamp:HMAC(password, 'timestamp+request-method+verb')
Ideally new schemes will be registered with IANA along with a specification. A registry is being setup to track auth schemes that have been developed. See http://tools.ietf.org/id/draft-ietf-httpbis-authscheme-registrations-03.html

Is it worth while to hide/obfuscate server connections in an iPhone app? If so how?

If I have an app that connects to Amazon's S3 service, is it worth my time to hide/obfuscate the connection strings and API keys? I'm guessing that most hackers won't care all that much, but it would be financially painful if someone found this information and was able to upload data to my account!
For instance, if I store a username/password (or Twitter/Facebook API key and secret), these may be easily found using "strings". A hacker could see the functionality, grab the secrets and use them for nefarious purposes. I've seen people suggest using a simple Rot13, or storing the strings backwards or something like that in the app binary. Are these useful?
Has anyone done this or have any ideas/patterns/code to share?
-dan
You can hide your secrets in a webserver you have full control over, and then having this server relay the query to Amazon. You can then use whatever encryption/validation method you like, since you are not relying on what is supported by Amazon.
Once you have validated that the request is from your own application, you then rewrite the query including your secrets and then forward this to Amazon. The result from Amazon could then be relayed directly back to the application.
In php this could for instance be done using something similar to this snippet (not showing your url rewrite):
$fp = fopen($amazon_url,'r',false);
fpassthru($fp);
fclose($fp);
You dont really need to hide them...what you should do is have an extra key such as a secret, that one IS hidden and is only present in the signature of the call (which can be an MD5 hash or sha (or whatever)) without that secret key people wont be able to just make calls since the signatures created by the server and the offender wont match since they dont know the secret key used...
I'm guessing that most hackers won't
care all that much
It just takes one who's bored enough.
Has anyone done this or have any
ideas/patterns/code to share?
This is what SSL is for. You can encrypt all your transmissions or just the login process (which would return a session id that can be used for subsequent requests during the session).

How to ensure access to my web service from my code only?

I am writing a very simple web service for my iPhone app. Let's say this is a http page that returns a random number at http://mysite/getRand. How do I ensure that this page can only be accessed from my iPhone app and not from other clients? I've thought of doing some simple password mechanism but that can easily be sniffed by capturing what my app sends out.
The reason for this is to lower the load of my server by only allowing legitimate requests.
You can't really do this. Your application can be disassembled and whatever secret is in the binary can be replicated in a malicious application.
Another attack you should be aware of is people settings the hosts file to a location they control and then installing a root certificate that allows them to provide a signature for that domain. Your application would do the post with the secret, and they'd just be able to read out the secret. They could extract the password from any complicated encryption system within the binary in this way.
Most of the ideas in this thread are vulnerable to this attack.
That said, the likelihood of somebody caring enough to disassemble your application is probably fairly remote.
I'd just keep it simple. Have a password that's hardcoded in to your application. To prevent someone just looking at the resources and trying every string, make it the XOR of two strings or the result of an AES decrypt of a particular fixed string.
Obviously, you should do the request over SSL otherwise an attacker can just sniff the traffic.
Yes, a determined attacker will circumvent the scheme but like any DRM scheme, that's always been the case. The trick is to make it too much effort to be worth it.
To follow up on Simon's idea, you could very easily have a key string in your application, then send the device ID, and then the DeviceID XOR'ed (or some other simple algorithm for string encryption) with your key string.
Since you know the key value to use, it's trivial for you to "decrypt" this string on the sever side and verify that the values match.
This way, the password is different for each user's device, and the "key" string is never sent over the wires of the great unwashed internets. :-)
Yes, this would by no means be impossible to figure out, but like others have said, the idea is not to make it impossible. The idea is to make it more trouble than it is worth.
I would use the https protocol with client-side keys too. You can use one client key for everyone or you can even generate a different key for each client and "register" them at your server.
I suppose that it's a lot of work for small project, but it sounds like the appropriate thing to do if you need authentication.
You should check that keys aren't seen easily by mobile phone owner. And remember that somebody will be able to hack it in any case.
Here's one thought - send up the device ID along with requests from your app.
Monitor the device ID's used - if you see a ton of requests from different IP's near or at the same time, that device is probably being used as a fixed key in the requests sent to you - block it.
For those that actually send the real device ID from other apps (not yours), you can monitor usage trends to see if the calls match the pattern of how your app performs - like one call being used by a device before some initialization call you would normally expect, and so on - block those too.
Basically by being able to shift rules around patterns of use, you can better adjust to someone trying to use your service by making sure it's not a fixed target like some random use key would be.
You may also want to use a simple use key as well as a first line of defense, and then layer on the traffic analysis approach. Also custom http header values you look for are another simple way to trip up a naive attacker.
I am assuming you don't want to use SSL? If you do then you can open HTTPS session and then pass some secret key in the request.
If you don't want SSL your options are limited: to have pseudo security I suggest both authentication and authorization methods and a third to reduce overall traffic:
Authentication: Generator in client application that creates secret keys by combining with a key file. The keyfile can be updated every so often for greater security: lets say you update the key file once a week. To re-cap: Generator combines in app secret with out of app key file to generate a 3rd key for transmission used in authentication. The server would then be able to authenticate.
Authorization: Of course you also want to lock out rogue applications. Here it would be best to have authorization mechanism with the site. Don't replace keyfiles for unless the client logs in. Track key files to users. etc.
Traffic reduction:
If you are receiving obscene amount of traffic or if you suspect someone trying to DOS your server, you can also have both the server and clients sync to request/response on a procedurally generated URL that can change often. It is wasteful to open/close so many HTTPS sessions if someone is just flooding you with requests.
I'm not sure what web technology you are using, but if you are using Ruby on Rails, it uses a secret authentication token in all of its controllers to make sure malicious code isn't accessing destructive methods (via PUSH, POST, or DELETE). You would need to send that authentication token to the server in your request body to allow it to execute. That should achieve what I think you are looking for.
If you're not using Ruby on Rails, that method of code authentication might be a good one to research and implement yourself in whatever technology you are using.
Take a look at the Rails Security Guide, specifically section 3.1 (CSRF Countermeasures).
You could do something like encrypting the current time and IP address from the iPhone, and then decrypt it on the server. The downside is that you need the iPhone app to know the "secret" key so that only it can generate valid access tokens... and once the key is in the wild, it will only be a matter of time before it's hacked if your app is really worth the effort.
You could encrypt the response using some random portion of the application which is meant to be using it, specifying the location of the binary in an unencrypted bit of the response. Then at least only clients with access to your binary would be able to decrypt it... but again, that's hardly 100% secure.
Ultimately you need to ask yourself how much effort you want to put into securing the service vs how much effort you think hackers will put into abusing it.
I'm not an Cocoa Touch developer, but I think HTTP Authentication over SSL would be easy to implement and it's probably exactly what you're looking for.
All you need to do is setup HTTP Authentication on the server side (you haven't mentioned what you're using on the server side) and create a self-signed SSL cert on your webserver. Done. :)
Tell us more about your setup and we will be able to help you further.
As some of the answers have stated, closing your web service off to everyone else will be a major hassle. The best you can hope for is to make it easier for the hackers to use another web service, than to use yours...
Another suggestion to do this, is to generate random numbers from a random seed on both the server and the client. The server would need to track where in the sequence of random numbers all of the clients are, and match that number to the one sent by the client.
The client would also have to register to be given access to the server. This would also serve as a authentication mechanism.
So:
//Client code:
$sequence = file_get_contents('sequence.txt');
$seed = file_get_contents('seed.txt');
$sequence++;
//Generate the $sequence-th random number
srand($seed);
for ($i = 0; $i <= $sequence; $i++) {
$num = rand();
}
//custom fetch function
get_info($main_url . '?num=' . $num . '&id' = $my_id);
This will generate a request similiar to this:
http://webservice.com/get_info.php?num=3489347&id=3
//Server Code: (I'm used to PHP)
//Get the ID and the random number
$id = (int)$_REQUEST['id'];
$rand = (int)$_REQUEST['num'];
$stmt = $db->prepare('SELECT `sequence`, `seed` FROM `client_list` WHERE `id` = :id');
if ($stmt->execute(array(':id' => $id)) {
list($sequence, $seed) = $stmt->fetch(PDO::FETCH_ASSOC);
}
$sequence++;
//Generate the $sequence-th random number
srand($seed);
for ($i = 0; $i <= $sequence; $i++) {
$num = rand();
}
if ($num == $rand) {
//Allow Access
} else {
//Deny Access
}
By using a a different seed for each client, you ensure that hackers can't predict a random number by tracking previous numbers used.