 |
Enigform: The OpenPGP Firefox Extension
by Arturo Busleiman, in Editorials - Sat, Apr 14th 2007 00:00 PDT
We all know about the benefits of digitally signing email messages using
OpenPGP-based software like GnuPG (or its older commercial counterpart,
PGP). Imagine the same benefits applied to the world of the World Wide
Web.
Copyright notice: All reader-contributed material on freshmeat.net
is the property and responsibility of its author; for reprint rights, please contact the author
directly.
In 1991, PGP, "Pretty
Good" Privacy, was created. Once the OpenPGP specification was released
as RFC
2440 [http://tools.ietf.org/html/rfc2440],
other vendors started to provide their own implementations, and the GNU
world had its own unleashed to the public with a more serious name -- GnuPG: The GNU Privacy
Guard (or, even shorter, gpg).
The most well-known userland usage of OpenPGP is email signing and
encryption (check out Enigmail for Mozilla
Thunderbird). By digitally signing your email messages, recipients
with OpenPGP-enabled mail user agents are able to authenticate the
email's sender and message. If the message body was modified in any way
during transport, the signature will not verify. This capacity for data
authentication is why many files available for download on the Internet
also provide an OpenPGP digital signature in a .sig file. OpenPGP is
much safer than MD5.
Email messages can also be encrypted to specific recipients, even the
sender herself, adding privacy to the equation. For the moment, though,
let's just focus on the "data authentication" part.
One night, approximately one year ago, I suddenly woke at 3:00 AM with
two crazy sets of words in my head: "BEGIN PGP" (part of OpenPGP content
and signature delimiters of signed/encrypted messages) and "GET /".
Signing HTTP requests with OpenPGP! I realized that could provide Web
servers and applications the ability to determine sender and data
authenticity. In other words, to know not only who sent a
request, but also if it was tampered with during transport (for example,
by a malicious transparent proxy sitting between the browser and Web
server).
Of course, I couldn't sleep, and my wife was not in the mood to
understand my ramblings, so I got up, wrote the idea down, and went back
to sleep.
About ten months later, I decided to create a Firefox extension to
implement my idea. The first publicly-released version only worked with
the HTTP POST method and was ugly, but functional. Basically, I
replaced the POST body with a signed version. This turned out to be a
bad idea because Web servers and Web applications that didn't understand
it would be broken.
I teamed up with Rodhri Pugh, author
of the Smutty PHP
MVC project, and we started a nice brainstorming of ideas. Smutty
was the first PHP framework to support Enigform... but it
was still ugly.
I decided I needed feedback. I contacted the IETF OpenPGP Working Group,
and via the mailing list, they said: "OpenPGP signing is implemented for
newsgroup posts as a set of extra headers. Why don't you use that?" So,
I did; I rewrote Enigform. There was no more HTTP POST body tampering,
just a set of HTTP headers added to each request: The signature itself,
a GnuPG version string, and a Digest Algorithm string.
That did it: I was able to attach a digital signature to every kind of
HTTP request (GET, POST, PUT, whatever) and even to AJAX-originated
requests. The latter was very nice for AJAX, since one of its main
mis-implementations lies in the authentication of those asynchronous
requests. All this came without breaking HTTP at all.
Now, let's see how a standard HTTP request looks, for example, for a
FORM submission:
POST /pba/test.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070226 Firefox/2.0.0.2
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/pba/
Content-Type: application/x-www-form-urlencoded
Content-Length: 14
variable=value
Here's the same request signed with OpenPGP:
POST /pba/test.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070226 Firefox/2.0.0.2
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/pba/
X-OpenPGP-Type: S
X-OpenPGP-Sig-Fields: body
X-OpenPGP-Sig: iD8DBQFF/cRKAlpOsGhXcE0RAjUbAJ0fTtRKlXPe6OMR4kS0pJ7rioOaPwCfQQ0Bmrai0UVXTkDV9KvNw0eDG1Y==EUzv
X-OpenPGP-Digest-Algo: SHA1
X-OpenPGP-Version: GnuPG v1.4.6 (GNU/Linux)
X-OpenPGP-Agent: Enigform 0.7.6 for Mozilla Firefox
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 14
variable=value
The request is still standard. A Web server or application that does not
know what the extra headers mean (and, more importantly, how to use
them) will do nothing but ignore them.
Let's do some further analysis on those headers:
-
X-OpenPGP-Type: S
-
This means the request is Signed. In the future, "E" for Encrypted and
"SE" for both Signed and Encrypted will be supported.
-
X-OpenPGP-Sig-Fields: body
-
This states which elements are signed, and in what order they were
submitted to the OpenPGP application. As you can see, only the "body"
of the request was signed. In the example, the body is the POST
payload, or "variable=value". In a GET request, the "body" would be
the QUERY STRING.
-
X-OpenPGP-Sig: iD8DBQFF/cRKAlpOsGhXcE0RAjUbAJ0fTtRKlXPe6OMR4kS0pJ7rioOaPwCfQQ0Bmrai0UVXTkDV9KvNw0eDG1Y==EUzv
-
This is the OpenPGP signature itself, converted from its standard
three-line form to a simple string.
-
X-OpenPGP-Digest-Algo: SHA1
-
This is the hash algorithm used, in this case SHA1. This depends on
what choices the OpenPGP application provides and what the user
chooses to use.
-
X-OpenPGP-Version: GnuPG v1.4.6 (GNU/Linux)
-
This is the OpenPGP application's name, version, and platform. This is
extracted from the "Version:" field of standard, signed, ASCII armored
OpenPGP output.
-
X-OpenPGP-Agent: Enigform 0.7.6 for Mozilla Firefox
-
This is the software that created the X-OpenPGP set of headers and
signed the fields. With luck, once I finish the Internet Draft and if
it gets to be a Standards Track RFC, some browsers will support
OpenPGP natively, and Enigform will no longer be needed.
Enigform Usage
To use Enigform, you just need Firefox 1.5+ and GnuPG. For the moment,
I'm testing with GNU/Linux, MS Windows, and MacOS X platforms, so if you
have another OS (like Solaris), please send me an email, and we will get
Enigform working for you and the rest of the community.
Enigform tries to detect where the gpg (or gpg.exe) binary resides.
Although I plan to enhance this area, for the moment it works like this:
Under GNU/Linux, it searches for /usr/bin/gpg. Under MS Windows, it
tries to get the installation directory for GnuPG from the registry.
Under OS X, it searches for /usr/local/bin/gpg (where macgpg gets
installed). If GPG is not found, it warns you and asks you to set the
full path to it in the Enigform Preferences window. If your OS is
not (yet) supported, it just tells you so. Please contact me if you get
that message, so more users can try and benefit from Enigform.
When Enigform detects a request whose URI ends in
#Enigform_Sign# (named anchors are safe to use in this
case, although I plan to enhance this by reading a special HTTP header
in a response), or if the "Always Sign" option is enabled, it will try
to sign the body. If the passphrase is unknown, it asks you to input it.
(Enigform can remember it if told to do so, and you can also clear it
from memory using a context menu item).
Enigform calls GnuPG and feeds the passphrase and request body using
random temporary filenames that are stored in a random new temporary
directory under your OS's temp directory. It also reads the signed
version from a file. It deletes the files and the directory that held
them as soon as possible, starting with the passphrase file.
Once the signed version is read, the required elements are extracted and
converted to the form we saw in the signed request example. The headers
are added, and the normal flow of the request is restored.
And that's it! The receiving Web application/server can act, or not,
accordingly.
By means of an Apache module I'm developing, mod_auth_openpgp,
adding Enigform support to Apache is very simple.
Although the module is still in development, it can be used to test this
new security schema.
Additionally, at the Enigform Test Site, you
can find some PHP code snippets for playing with Enigform. The Smutty
source code for the Smutty_GPG
class is another invaluable resource.
I hope you like the idea, and I wait for your comments!
Author's bio:
Arturo "Buanzo" Busleiman is
a 25-year-old programmer from Buenos Aires, Argentina who has been using
and developing for GNU/Linux for the past 12 years. He's crazy about
security, programming, and guitar playing.
He has contributed to many groups and projects, including OISSG's ISSAF,
SANS TOP-20, Nmap, Audacity, Samba-Vscan, and mprl. He also loves giving
speeches about hacking, networking, and programming, and dreams about
Defcon, Blackhat briefings, et al. He works as an independent
consultant, specializing in GNU/Linux and Security. You can meet him at
the Argentinian
2600 meetings.
T-Shirts and Fame!
We're eager to find people interested in writing articles on
software-related topics. We're flexible on length, style, and
topic, so long as you know what you're talking about and back up
your opinions with facts. Anyone who writes an article gets a
t-shirt from ThinkGeek
in addition to 15 minutes of fame. If you think you'd like to try
your hand at it, let jeff.covey@freshmeat.net
know what you'd like to write about.
[Comments are disabled]
Comments
[»]
https and certificates?
by Soenke J. Peters - May 5th 2007 08:59:42
IMHO this method has no advantages over good old HTTPS connection and
personal certificates.
Using Apache's mod_ssl with ExportCertData enabled, you can
even do deeper checks of the certificate in your server-side scripts or
use information contained therein for script-side authentification (see
FakeBasicAuth option of mod_ssl).
[reply]
[top]
[»]
Re: https and certificates?
by Buanzo - May 13th 2007 09:36:20
> IMHO this method has no advantages over
> good old HTTPS connection and personal
> certificates.
>
> Using Apache's mod_ssl with
> ExportCertData enabled, you can even do
> deeper checks of the certificate in your
> server-side scripts or use information
> contained therein for script-side
> authentification (see FakeBasicAuth
> option of mod_ssl).
Sure. I said nothing against SSL :) - But you have some important
differences:
1) SSL = for the whole connection. it's socked-based. you might not want
that.
2) web-of-trust approach versus hierarchy-based approach
3) although you can be your own CA, if you want to avoid the hassle of
telling your users to have your root cert into their browsers or whatever,
then you need to spend lots of money on ssl certificates.
4) message-based, not socket-based.
5) you can mix openpgp signed requests (which are VERY flexible from
web-developers and designers' perspective) over HTTPS.
6) it's good to have alternatives. :)
[reply]
[top]
[»]
Re: https and certificates?
by Mike Acker - Nov 1st 2007 11:33:30
> IMHO this method has no advantages over
> good old HTTPS connection and personal
> certificates.
>
> Using Apache's mod_ssl with
> ExportCertData enabled, you can even do
> deeper checks of the certificate in your
> server-side scripts or use information
> contained therein for script-side
> authentification (see FakeBasicAuth
> option of mod_ssl).
personally, I think the biggest risk on the Net today is simple surfing:
user may be browsing what is normally a reliable site but clicks on a link
that interests him and this link could very easily lead into the back alley
where the RATS live.
The site the user came from is most likely well intentioned. but the
character of the destination may have changes either by revisions made by
the web authors or by some kind of DNS spoofing
which is why it is critical to establish and enforce the simple rule No
Signature: No Execute as far as anything executable goes.
Hopefully we can prevent the RAT from getting his signature approved by
the Certificate Authority but we should discuss auditing of software
distributions separately. For starters we kill all un-authorized
executables on the spot.
-- Mike Acker
[reply]
[top]
[»]
EnigForm
by Russell Valentine - Apr 14th 2007 08:57:51
This is a interesting idea. It brings a lot of possibilities. In a similar
manner an apache module could be made in which returned requests from the
web server could be signed/encrypted. This will be very helpful in
instances where you have the need for a lot of virtual hosts but a lack of
IP's. This method will allow authentication or encryption and yet not
require a separate port for SSL.
If you did have SSL there are already ways to authenticate the known users
using signatures.
http://www.modssl.org/docs/2.8/ssl_howto.html#ToC6
Enigform looks to give you more control, without having the server to
touch the client cert for signing.
Also I wonder, why can't you keep the pass phrase in memory only instead
of writing to a temp file?
[reply]
[top]
[»]
Re: EnigForm
by Buanzo - Apr 14th 2007 11:04:46
> Also I wonder, why can't you keep the
> pass phrase in memory only instead of
> writing to a temp file?
Hi! Thanks for your comments. Enigform 0.8.0 supports gpg-agent. When the
Agent is not used, passphrase is sent to a temp file on a random directory
under the OS's native temp dir each time a signed request is sent. Then,
with gpg's --passphrase-file parameter, it is read. After it is sent, the
file and directories are deleted. Passphrase is kept in memory if user
chooses to.
Maybe I do not understand your question correctly.
I'd love to use --passphrase-fd, but I want to avoid using the Javascript
IPC Component, because I'd be limiting to the platforms JSIPC supports. I
might end up doing that for 1.0.0, and fallback to the current methodology
on unsupported OSes.
[reply]
[top]
[»]
Re: EnigForm
by Russell Valentine - Apr 14th 2007 13:10:51
>
> % Also I wonder, why can't you keep the
> % pass phrase in memory only instead of
> % writing to a temp file?
>
>
> Hi! Thanks for your comments. Enigform
> 0.8.0 supports gpg-agent. When the Agent
> is not used, passphrase is sent to a
> temp file on a random directory under
> the OS's native temp dir each time a
> signed request is sent. Then, with gpg's
> --passphrase-file parameter, it is read.
> After it is sent, the file and
> directories are deleted. Passphrase is
> kept in memory if user chooses to.
>
> Maybe I do not understand your question
> correctly.
>
> I'd love to use --passphrase-fd, but I
> want to avoid using the Javascript IPC
> Component, because I'd be limiting to
> the platforms JSIPC supports. I might
> end up doing that for 1.0.0, and
> fallback to the current methodology on
> unsupported OSes.
>
>
Yeah, I think you understand correctly.
You'll have to forgive me as I haven't written any addon's for Firefox or
Thunderbird. I was looking through Enigmail and Enigform source to try to
see the difference in the handling of the passphrase. I may be mistaken
but it looks like Enigmail never writes the passphrase to file.
Even though the passphrase is deleted soon after, since it is written to
disk it is possible yet unlikely to recover it from the disk in case it
was stolen or something.
In any case it isn't a big deal, I shouldn't have brought it up. Keep up
the good work.
From my previous post, you can see I'm much interested to see this as a
possible replacement for SSL. Reading from your other documents it seems
your main goal is client-server authentication though gpg and the
server-client communication can be done through regular SSL. Is it part of
your future goals to have the server-client communication work in a similar
way as you have the client-server stuff going on now?
If not this is still very cool and a lot better than the typical
user-password scheme. This could be a good way to prevent those scam
'paypal', 'ebay' emails from working. Even if the scammers receive valid
signed requests, to prevent abuse websites just need to have the request
include a shared random seed parameter.
[reply]
[top]
[»]
Re: EnigForm
by Russell Valentine - Apr 14th 2007 13:23:54
> If not this is still very cool and a lot
> better than the typical user-password
> scheme. This could be a good way to
> prevent those scam 'paypal', 'ebay'
> emails from working. Even if the
> scammers receive valid signed requests,
> to prevent abuse websites just need to
> have the request include a shared random
> seed parameter.
Actually after I submitted the comment I realized, to prevent the scams we
need more than just a shared random seed. I believe the plugin would also
have to send some parameter always like some dummy parameter (such as the
full actual url) that can't be overriden. As just a shared random seed can
still be vulnerable to the scams, because the random seed request could
just be relayed through the scammers site to the client. Random seed
parameters would prevent abuse at a later time though when the user is not
currently using the scam site.
I don't know if scam prevention was part of your goals. I did read in your
comments you originally sent this idea to Goggle so maybe it was. I believe
there is still much to think of with such a scheme to make it secure.
[reply]
[top]
[»]
Re: EnigForm
by Buanzo - Apr 14th 2007 13:57:31
> I don't know if scam prevention was part
> of your goals. I did read in your
> comments you originally sent this idea
> to Goggle so maybe it was. I believe
> there is still much to think of with
> such a scheme to make it secure.
Yes, although it still needs much work (making it at least usable is the
first step to get good community feedback, I'm a full-disclousure and
security-through-clarity guy), anti phishing / scam prevention are one of
my goals.
As you saw, I decided to focus on Identity and Data authentication of
client at server, but of course I'm also thinking about the same scheme in
reverse.
Additionally, Encryption WILL be implemented some day in the near future,
although this is now something I have in my mind because of your comments
regarding SSL and multiple virtualhosts on the same IP: it's a good thing
to implement and lots of people might benefit from it.
To prevent scams, all that is needed is the server identifying the client,
and the client identifying the server. If they both can trust each other,
as no other credentials (passwords, PINs, etc) are needed, then phishing
becomes useless.
For example, a fake paypal site that requests my username and password
would simply not work, as there is no username (well, email address
actually) and password. There is only signed http requests that get into
paypal, that paypal can verify as belonging to that user, and they also
can be sure the data has not been tampered with.
Okey, the private key and the passphrase could still be stolen, but that's
a whole other issue.
[reply]
[top]
[»]
Re: EnigForm
by Paul Vital - Aug 8th 2007 00:10:05
>
> % I don't know if scam prevention was
> part
> % of your goals. I did read in your
> % comments you originally sent this
> idea
> % to Goggle so maybe it was. I believe
> % there is still much to think of with
> % such a scheme to make it secure.
>
>
> Yes, although it still needs much work
> (making it at least usable is the first
> step to get good community feedback, I'm
> a full-disclousure and
> security-through-clarity guy), anti
> phishing / scam prevention are one of my
> goals.
>
> As you saw, I decided to focus on
> Identity and Data authentication of
> client at server, but of course I'm also
> thinking about the same scheme in
> reverse.
>
> Additionally, Encryption WILL be
> implemented some day in the near future,
> although this is now something I have in
> my mind because of your comments
> regarding SSL and multiple virtualhosts
> on the same IP: it's a good thing to
> implement and lots of people might
> benefit from it.
>
> To prevent scams, all that is needed is
> the server identifying the client, and
> the client identifying the server. If
> they both can trust each other, as no
> other credentials (passwords, PINs, etc)
> are needed, then phishing becomes
> useless.
>
> For example, a fake paypal site that
> requests my username and password would
> simply not work, as there is no username
> (well, email address actually) and
> password. There is only signed http
> requests that get into paypal, that
> paypal can verify as belonging to that
> user, and they also can be sure the data
> has not been tampered with.
>
> Okey, the private key and the passphrase
> could still be stolen, but that's a
> whole other issue.
>
>
>
>
I like this plugin very much. Any idea when there will be a new version?
There are some features I am missing, would be cool if anybody can update
this and add some more features! Bye, Paul.
[reply]
[top]
[»]
Re: EnigForm
by Mike Acker - Nov 1st 2007 11:05:10
To win we must beat the RAT and we must beat him by a complete shut-out.
Which means: No Signature: No Execute.
Once that has been done on the communication link finishing the issue will
require some kind of auditing for software that we do allow to be
distributed.
One other thing too: and that is about Certificate Authorities: we will
have to insist that everyone appear in person with identification at the
Certificate Authority or at an authorized agent thereof such as a Credit
Union, Office Max etc. in order to obtain the public key for the
Certificate Authority and to register personal public key.
PoC Mike Acker
napfn@net-link.net
-- Mike Acker
[reply]
[top]
[»]
Re: EnigForm
by Buanzo - Nov 15th 2007 10:23:01
> I like this plugin very much. Any idea
> when there will be a new version? There
> are some features I am missing, would be
> cool if anybody can update this and add
> some more features! Bye, Paul.
I'm glad oyu like the plugin. I'll be releasing a new version, along with
a new release of mod_openpgp in the next few weeks.
News? Well, a Secure Session Initiation Protocol has been implemented.
You're gonna LOVE it.
Imagine this:
A webmaster has a site on an OpenPGP-enabled Apache server, and wants to
avoid having to implement a username/password based login system. So he
just implements a signup mechanism that asks users for their pgp public
key.
Then, he just adds a special "Login" link to his page, and all
Enigform-enabled browsers will be able to click on it, start a session,
and be automatically authenticated.
The protocol is a challenge/response mechanism which uses openpgp
encryption/decryption to accomplish its goal.
From then on,e ach request that goes to the server will be signed, and
have this sesison hash embedded, thus the apache server can determine if
the sesison is valid, invalid, or timed-out :)
[reply]
[top]
|
 |