I am developing a webapp with Ruby on Rails and need to be able to call some functions from authenticated remote servers and then stumbled across this solution. It sounded very interesting to me and I started to play around and read your code and get more into OpenPGP. As far as I understand the code, at the moment either only the value of the QUERY_STRING or the body are signed depending on the request (GET, resp. POST). This places a few questions about its usability, especially for my use case, where path information directs the actions of the webapp. Let's say I have some request like

My security concerns with signed request

The ability to sign other elements of the request is already in the TODO list. Actually, the X-OpenPGP-Sig-Fields header has the default/fixed value of "body", which means exactly what you've described: Query string, or POST body.

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.

I want to add that i fully agree with your security concern, and I'm open to any suggestions of how to implement this new element.

Ah, I didn't see your freshmeat page before, so there is some space for improvements already laid out :-)!

I did some thinking of how I liked to get the signed requests arrive at my server and I found out that the best would be if simply everything (request line, headers and body) would be signed as it would give me the best certainty that nothing would have been changed.

However after being introduced to your 'X-OpenPGP-Sig-Fields:' header, I start to get the feeling that this would not be easy/possible to implement. First of all I can imagine that you cannot guarantee that enigform (or any other implementation) is the last code that does fool around with the request. So possibly not every request header line is already done. On the server side you would then have to make sure that the string you are creating for verification is exactly the same. My tests with WEBrick (http server written in Ruby) showed that the headers are put in a hash table and the order when iterating over it is random. So I guess this is one reason you needed to have the 'X-OpenPGP-Sig-Fields:' header.

So it would be cool if at least something like

X-OpenPGP-Sig-Fields: request_line, host, cookie, body

would be possible and if some of them are missing they would be ignored. This however imposes that a server app possibly needs to deal with positively verified requests that has other 'X-OpenPGP-Sig-Fields:' being signed and verified, meaning that the server app can't only parse the 'X-Auth-OpenPGP' for authorization, which is in my opinion unnecessarily complicated.

Another problem I see: If a man-in-the-middle intecepts a request from a client asking to get the bank account summary, the request. it will be the same every time, so the interceptor can send the same request again and get the information. To avoid this behaviour, there needs to be some challenge response mechanism. I don't know yet what could be an appropriate way to do.

Let me know if I can do something for the project. I will hack around with WEBrick in the meantime.

dinkel escribió:I did some thinking of how I liked to get the signed requests arrive at my server and I found out that the best would be if simply everything (request line, headers and body) would be signed as it would give me the best certainty that nothing would have been changed.

As you realize later, I can't guarantee nothing regarding request-modification. So far, taking into account the request_line, and get/post body, and maybe a couple of headers would be OK... there are also another issues that are out of my control, like transparent proxies that add/remove/modify headers, etc... that means the LEAST number of signed fields, might be the better.

dinkel escribió:My tests with WEBrick (http server written in Ruby) showed that the headers are put in a hash table and the order when iterating over it is random. So I guess this is one reason you needed to have the 'X-OpenPGP-Sig-Fields:' header.

You're quite right. My original discussions with the OpenPGP Working Group at the IETF presented those kind of situations.

dinkel escribió:This however imposes that a server app possibly needs to deal with positively verified requests that has other 'X-OpenPGP-Sig-Fields:' being signed and verified, meaning that the server app can't only parse the 'X-Auth-OpenPGP' for authorization, which is in my opinion unnecessarily complicated.

Certainly. The least the web-application needs to worry with 'sessions', 'authentication' and such, the better.

Another problem I see: If a man-in-the-middle intecepts a request from a client asking to get the bank account summary, the request. it will be the same every time, so the interceptor can send the same request again and get the information. To avoid this behaviour, there needs to be some challenge response mechanism. I don't know yet what could be an appropriate way to do.

Run signed requests over SSL, or wait until Enigform/mod_auth_openpgp support OpenPGP encryption/decryption.

dinkel escribió:Let me know if I can do something for the project. I will hack around with WEBrick in the meantime.