Valhalla Legends Forums Archive | Advanced programming | Securely passing responsibility between trusted entities

AuthorMessageTime
Arta[vL]Ok, I wanted to bounce this off people to see if I've missed anything important.

A job I'm working on at the moment requires that I pass a user from a non-secure server (A) to a secure server (B) for the purpose of registration and payment. After they've registered and paid, they need to be passed back to the non-secure server to continue their visit.

I need to make sure that users can't just skip the secure server and proceed directly to 'continuing their visit'. I don't want to do something hackish like adding a field to the database to use as a flag (eugh). I've come up with the following:

When A is sending a user to B, A hashes a prearranged secret with a salt value. It then sends the hash and the salt to B. B hashes the salt with its copy of the secret, and checks that the hashes match before allowing the user to continue. When B sends the user back to A, it does the exact same thing (with a different salt). Thus, the user cannot skip B, because the final stage of A will require a correct hash before the user can continue. Avoiding reuse of the salt prevents a replay attack.

Thoughts?
July 19, 2005, 09:46 AM
NewbySounds good. I would have recommended that you pass some sort of value from A -> B, so that B can give it back to A (changed or not) when the user returns from B to A, to prove he was there.July 19, 2005, 01:56 PM
dxoigmnI assume you are using different secrets for each direction?July 19, 2005, 04:19 PM
NewbyPerhaps base the value off of the current time.July 19, 2005, 06:09 PM
Arta[vL]
Perhaps base the value off of the current time.

That would be a terrible idea - a predictable secret would make the scheme much less secure.

I assume you are using different secrets for each direction?

I'm not sure that's necessary. Would that really be more secure, or would it just be paranoia?

Sounds good. I would have recommended that you pass some sort of value from A -> B, so that B can give it back to A (changed or not) when the user returns from B to A, to prove he was there.

hmm, why?
July 19, 2005, 08:13 PM
KpBasing it off the current time isn't necessarily predictable.  Consider if the necessary value is determined as pub = (time() * X) % Y, where X and Y are 64bit (or larger) integers known only to your servers.  Then pub will automatically change over time, but also be difficult to predict without knowing X and Y.  To compensate for clock drift, you could round time down to the nearest Nth time unit, e.g. nearest minute.  Even if someone does figure out X and Y, you can change them easily, thus rendering moot the work done by the attacker.July 19, 2005, 08:51 PM
R.a.B.B.i.TI thought about it a bit and that sounds like a way to double confirm (IE: "A - im giving you bob; B - okay, got bob, now im done and giving him back; A - got him; B - you sure?; A - yep!").  B would confirm A sent Bob to B from A (grr I hate that sentence), do what B needs to do, then send Bob back with a note proving it was Bob and not John who was actually there.  iago and his paranoid ways would probably be able to explain it better with one of his flow charts, but eh.July 19, 2005, 08:52 PM
Arta[vL]
Basing it off the current time isn't necessarily predictable.  Consider if the necessary value is determined as pub = (time() * X) % Y, where X and Y are 64bit (or larger) integers known only to your servers.  Then pub will automatically change over time, but also be difficult to predict without knowing X and Y.  To compensate for clock drift, you could round time down to the nearest Nth time unit, e.g. nearest minute.  Even if someone does figure out X and Y, you can change them easily, thus rendering moot the work done by the attacker.

If the secret isn't prearranged, then it would have to be transferred securely between A and B. That introduces a host of other problems that I don't want to deal with. I think it'll be fine to prearrange a secret and change it occasionally.

Rabbit: not sure what you're getting at. Why is a double-confirm beneficial? Doesn't it just add complexity?
July 19, 2005, 09:37 PM
R.a.B.B.i.TI was just goin off what Newby said :\

If you want max security, a double-check isn't a bad idea.
July 19, 2005, 09:59 PM
Arta[vL]It could easily be a bad idea. It could introduce unnecessary complexity, and thereby increase the attack surface of the system. The more complicated it is, the more can go wrong.July 19, 2005, 10:08 PM
AdronMaking sure salts aren't reused is important. A should know what it's going to get back from B already when it sends the user off to get it. That way, there's no risk of the user finding a way to reuse a payment confirmation. If B generates a salt in some random way and A just accepts it, I don't see how you could prevent that.July 20, 2005, 09:23 AM
Arta[vL]A just accepts it because of the hash. A rehashes the secret and the salt, compares the hashes, and can thus be sure that B knows the secret. The security lies in the secret, not the salt - the salt is only there to prevent sending a hash of the secret by itself, which would allow a replay attack. And yes, the salt should be different every time, for the same reason.July 20, 2005, 09:40 AM
Adron
A just accepts it because of the hash. A rehashes the secret and the salt, compares the hashes, and can thus be sure that B knows the secret. The security lies in the secret, not the salt - the salt is only there to prevent sending a hash of the secret by itself, which would allow a replay attack. And yes, the salt should be different every time, for the same reason.


What I meant was that after user X has gotten salt1 hashed from B and sends it to A, you need to be really sure that user Y can't get the salt1+hash from user X and use that as proof that user Y has paid as well. Or that user X can't reuse his salt1 tomorrow when he's buying something else. Or that user X can't reuse his salt1 after A has been rebooted, or after the database has crashed or ....
July 21, 2005, 07:13 AM
Arta[vL]hmm, I see what you mean. As it turns out, this is no longer a problem. Nonetheless, it's interesting Smiley

How would you solve that?
July 21, 2005, 12:05 PM
Adron
hmm, I see what you mean. As it turns out, this is no longer a problem. Nonetheless, it's interesting Smiley

How would you solve that?

You might include current date/time and transaction id. You might include the user id. Lots of things that ensure that this particular hash is only valid for what you want it to be valid for.
July 22, 2005, 02:22 AM