Reputation: 2844
Context
We have an application A
that guides our customer consultants throught a workflow based process. Part of this process has been outsourced to a own webapplication - lets call it application B
.
Wenn calling application B
the certificate of the current user is used for the HTTP
s connection (since it just delegates the HTTP
GET
to a new browser window).
Application A
has the required data to autorize users to perform certain actions while application B
expects the autorization to be done once a URL
is called.
Application A
must as well deliver certain data such as IDs to enable application B
to know for example what customer is beeing processed.
Requirements
That application B
can expect the autorization to have been done it must be ensured that only application A
was the source of the call and the user has not changed the parameters of the URL
(which he can as it is his certificate that is used for the HTTPS
connection).
What have we done
We thought of building a hash over the parameters, encrypt it with the private key of application A
and submit it as additional parameter with any request. Application B
uses the public key of application A
to decrypt the hash, build a hash over the received parameter and check that parameters have not been changed.
My Question
What would be other possibilities to ensure the source of the call was application A
and the parameters have not been changed by the user?
(If not clear please leave a comment i am currently painting some grafics and can overwork the question).
Regards JBA
Upvotes: 0
Views: 57
Reputation: 15599
So A signs the parameters for B, which is a step in the right direction.
A few more things to consider:
Replay attacks. A malicious user of B might observe a desired set of parameters signed by A. He can replay those anytime in the future, along with the valid signature from A, even if A did not intend to call B with those parameters anymore (say the authorization information changed). To mitigate this, a nonce or a timestamp should also be signed in the request and checked by B when validating the signature (the nonce should be checked for uniqueness, the timestamp for not being too old).
Participants (who's messaging whom). When A signs the message, the signed data should contain the intended recipient, so that an attacker cannot take a message from A to C, and send it to B. Of course if all of your components have a single instance, that's less of an issue, but still A should include something like the message is for B's url, and B should check that the url signed is actually the right one. Similarly, A should include the information that it was signed by A (his own url or IP address for example), and B should validate that the apparent and signed sender are the same.
Not creating a signing oracle. You should make sure that a user cannot use A as a signing oracle for making signatures. The less data a user of A can choose himself for A to sign, the better.
By the way (and apart from all of this), wouldn't it be simpler if B could just query A over some kind of an API request for all the information it needs? That way you wouldn't have to bother with all the relatively complex crypto stuff and would not have to pass sensitive info through the user.
Upvotes: 1