HTTP Request/Response signing standards - http

I want to sign the payload of HTTP Requests and Responses. The signature should reside in the header. The signing mechanism should not require any change in existing payload structure.
The main use case is non-repudiation.
There are many custom ways of doing it but I am looking for a standard.
If possible there should be support for signature verification without having to manually seed each application with other applications' public keys (the way Public Key Infrastructure it works with SSL certs)
Is there an existing standard that does this?

Yes, there is an IETF draft for signing HTTP.
https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/
To the question about PKI, you can do certificate distribution in the signed headers so if you do have a root of trust for the keys you don't need to copy the individual public keys around.

Related

Cross domain HTTP POST authentication

We're looking to implement a simple authenticated HTTP POST integration between two web applications, and while something like JWT should work, it seems overkill.
Use case:
Application A sends a POST via https to Application B with a hidden form and target=_blank.
Application B reads parameters from the POST body, validates and authenticates it, and redirects the user to the correct content further in Application B.
Application B's session cookies are persisted with SameSite=None to capture existing sessions in the same browser.
Application A's and B's servers can be assumed to be in separate restricted environments, so all traffic must go through the browser.
I'd like to avoid having to exchange certificates, a simple text based shared or asymmetric secret would be ideal, if sufficient.
We already have another integration where the sender sends the following:
Payload
Timestamp
Hash combining payload, timestamp and a shared secret
The receiver checks if the sent hash matches a hash that is calculated by the receiver, so essentially an HMAC with a timestamp to prevent stored repeats (but dupes are not protected against, which was fine in this case). I figured adding a nonce which is cached on the receiving end would prevent dupes and just ignore CSRF as we're authenticating every request, but it just seems like this is a problem already solved by people more qualified and I should be using an existing standard or implementation.
Any recommendations? We're using .NET in case that affects library recommendations.
After further research, TOTP (Time-based One-Time Password) is what we'll be going with. It meets all of our requirements, only needs a shared secret to be configured at both ends, and there are plenty of existing libraries to use.

C# BasicAuthentication implementation approach

I am thinking of creating a web api application using .Net. Here is what I am thinking of how to implement this.
The application will be serving clients who's credentials I will create separately.
These credentials will be encrypted using my own private key.
I will provide them this encrypted text.
They will use this encrypted text in the Authorization header.
On the server I will implement an AuthorizationFilterAttribute.
In here I will decrypt and validate the user.
And allow it to go to the resource.
I honestly do not understand this topic in depth. Therefore I was wondering if my approach will work.
In my tests I have seen that all requests do hit the AuthorizationFilterAttribute which means I will have the chance to check credentials on every request.
Bearer Token might not work as for that I will need (my understanding) at least 2 requests one to get token and next one to get actual resource. Please guide.
Thanks

HTTP header to allow client to choose JWT algorithm

I have a resource that generates a tokens for users. I want to add possibility choose token generation algorithm.
I can't change request structure but can add some HTTP header with the algorithm name. My question is what header to choose? Would Accept be acceptable?
I currently use a Accept-Token-Algorithm header to send values like RS256 and HS256.
My question is what header to choose? Would Accept be acceptable?
There's no standard header for that purpose.
If both client and server agree with Accept-Token-Algorithm, that seems to be a reasonable choice. More descriptive (and verbose) alternatives would be Accept-Token-Signature-Algorithm (assuming the JWT is actually a JWS) and Accept-Token-Encryption-Algorithm (for JWE).
Keep in mind that your API is as good as the documentation you provide for it and custom headers are not obvious to API consumers. So ensure that you document it properly.
You also should consider falling back to a default algorithm if the desired header is not present in the request and ensure that you validate the values you receive. Refer to the RFC 7518 for a list of valid algorithm for each purpose:
Digital signatures and MACs
Content encryption
Key management for JWE
Have a look at this page for details on how to choose algorithms for JWT.
If you need to add a custom header to your request see Custom HTTP headers : naming conventions
That being said, I don't see any reason for the client to choose the signature algorithm. The signature choice should be decided by the service issuing it and should depend on security tradeoffs acceptables for this service.
APIs accepting this token should be able to verify the signature of this token. So it is APIs consuming this token that should be able to accept the same encryption algorithm and should have access to corresponding public keys (or shared secret) that was used when issuing the token.
If the contents of the token (payload) are useful for intermediary parties, it can be decoded (base64) withouth any knowledge of the encryption algorithm used to sign the key.
If the token is issued for a third party service (such as in oauth2 protocol), the token should be opaque for this kind of actors.

Backbone HTTP basic rest api authentication

I am using Backbone.js and it communicates with a stateless rest API. Some calls require authentication, through HTTP basic.
What I don't understand is, somehow I have to authenticate each request, how could I do this securely? My first thought was to have a cookie, store the username and password but this would be vulnerable?
Can this be done securely?
There are two themes to this question. One is about security and one seems to be about REST rules.
The way to do authentication securely, is to pass that data through an SSL connection. It's the only way to securely transfer data over the wire.
With regards to sending authentication using basic auth over each request (REST), not many people I know do this in reality.
There's always a big long discussion on how much security is enough security and it really depends on your application and what the purpose is. I know this isn't the definitive answer you might be looking for but I'll just give you my take and how I'm going about dealing with the issues you mention.
With RESTful apps, the story is one should authenticate each request but in real practice I find this is more a "guide" than a hard rule. Rare is the fully RESTful application that follows all the rules. I use an encrypted cookie to store the user session data with a standard authentication flow that happens once and expires in a week. Data transfers happen through SSL to prevent MITM attacks and a modified Backbone sync sends a CSRF token along with each POST, PUT, DELETE to prevent cross site request forgeries. Probably "good enough" for the social app that I am working on. Maybe not if you're doing bank wire transfers and stuff. Hope this sort of gives you a point of reference in judging what you might want to do.
Is https://github.com/fiznool/backbone.basicauth something you'd find useful?
This plugin enables access to remote resources which are protected by HTTP Basic Authentication through your Backbone Models and Collections.
How does it work?
A resource protected with HTTP Basic Authentication requires the following HTTP header to be set on every request:
Authorization: Basic
The access token is formed by taking the username and password, concatenating together with a : separator and encoding into Base64.
This plugin handles the Base64 encoding and automatically sets the Authorization header on every request which uses Backbone.sync.

Using RSA (with openssl) in opposition to HTTPS

I am planning to implement API security in my REST application, Where i need work for authorization URL (on server PHP application) which will return a session token to client (mobile clients android, iphone, BB, wp7, wp8)requesting this url.
After looking for possible solutions i found these two perfect for my needs. but i am not able to decide on solution which will survive me on long runs.
Using RSA encryption with openssl for transferring user data to authorization URL (i am going with openssl just to stick with standard and secure method).
I have a hunch that it's possible to just use HTTPS to pass the user data and let OS handle encryption/decryption.
However, I am particularly inclined to first approach, since here client will not be able to make successful call to authorization url unless it has access to public key. But i am not sure about how well this approach will gel with all mobile clients.
Any help on this is much appreciated!..
You should be ok when sending the authentication URL over SSL. SSL will authenticate the server and make sure that the data is protected against eavesdropping and man in the middle attacks. The URL will then be send over this protected channel, so after verifying the URL, the server can determine that the client is indeed the right entity. The token can then be safely send to the client over the same SSL session
If you go with your own scheme you will have to setup your own key management scheme and protocol. This is extremely hard to get right. Your comment on having access on a public key is a good indication that you will fail. SSL is not perfect either, but it has had a lot of scrutiny, and chances of it failing out of the blue are slim.
In other words, choose #2 over #1.

Resources