Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add simple anti front running fix #574

Merged
merged 7 commits into from
Feb 12, 2020
Merged

feat: add simple anti front running fix #574

merged 7 commits into from
Feb 12, 2020

Conversation

kevsul
Copy link
Contributor

@kevsul kevsul commented Feb 4, 2020

Simple front running protection.
Challenger has to provide data derived from sender, so that simply re-submitting the tx with a higher gas price doesn't work

https://github.com/omisego/security-issues/issues/11

There have been 3 options proposed:

  1. Add the sender's address (or hash of it) as a parameter to the challenge functions
  2. Add signature body (65bytes) into the tx and check if the msg.sender is the same as signer of the signature.
  3. PoW concept - so:
    hash(txbytes || nonce || sender) = "0x00000000" <> anything
    then contract code would just compute additional hash and check required zeros

Option 1 is obviously the simplest to implement for both the contracts and the callers, and should defeat most generic front running scripts. Defeating front runners who are specifically targeting challenges will probably require more thought.

@boolafish
Copy link
Contributor

A question, why sha the address instead of checking address directly?

Copy link
Contributor

@pdobacz pdobacz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but noticed 2 things (see comments)

@@ -74,6 +74,8 @@ library PaymentChallengeIFENotCanonical {
)
public
{
require(args.senderData == keccak256(abi.encodePacked(msg.sender)), "Incorrect senderData");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't the "respond to non-canonical challenge" (not sure of the exact name) require one as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, good point. But maybe neither "challengeInFlightExitNotCanonical" nor "respondToNonCanonicalChallenge" need this protection right now.

That's because the IFE bond doesn't get paid out on a canonical challenge or response - the owner of the bond is changed here, but the bond doesn't get paid out until processExit is called.

So while a front runner could potentially benefit by front running a canonical challenge or response, they would have to be very familiar with how the exit game works.

Um. I'm inclined to add it in anyway though, for consistency with the other methods, and possible an easier path to adding more sophisticated front running protection later.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah you're right! I'd definitely vote for consistent, to not surprise our future selves reading the code.

Just the question now is - what will be consistent:

  • senderAddress on anything resembling a challenge and related to any bond operation or
  • senderAddress on anything that actually can pay anything out.

On 2nd thought, the latter makes more sense, so it seems it should be dropped from challengeIFENotCanon.. The downside I see is that if sometime, someone decides that those call should pay some portion of the bond (for whatever reason), they'd have to remember to do senderAddress check.

Not 100% sure here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going with option 2; only putting senderData on anything that actually pays out.
Trusting our future selves to do the right thing if or when we implement a more sophisticated front running solution

@@ -59,6 +59,7 @@ library PaymentInFlightExitRouterArgs {
uint256 competingTxPos;
bytes competingTxInclusionProof;
bytes competingTxWitness;
bytes32 senderData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the integration docs and the .md files documenting the contracts reflect this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, will update them

@kevsul kevsul requested a review from pdobacz February 6, 2020 14:38
pdobacz
pdobacz previously approved these changes Feb 7, 2020
Copy link
Contributor

@pdobacz pdobacz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! one typo spotted

@@ -547,7 +547,8 @@ PaymentExitGame.challengeStandardExit({
exitingTx,
challengeTx,
inputIndex,
witness
witness,
spenderData
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

senderData? (multiple occurrences)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch!

boolafish
boolafish previously approved these changes Feb 7, 2020
Copy link
Contributor

@boolafish boolafish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation LGTM. Approve to unblock.
But can you update the description of the PR to explain the approach a bit especially on my previous comment of why doing sha instead of checking address directly.

@kevsul
Copy link
Contributor Author

kevsul commented Feb 10, 2020

Wow, sorry @boolafish - I typed out an answer for this last week, but it must not have got sent correctly 😞

A question, why sha the address instead of checking address directly?

It's to (slightly) obfuscate the sender address, so that a script won't simply replace it with their own address

@kevsul
Copy link
Contributor Author

kevsul commented Feb 10, 2020

Dammit, I had a longer description as well, but it got lost too! 😠

I'll try to remember what I wrote originally...

@kevsul kevsul dismissed stale reviews from boolafish and pdobacz via efadd2c February 10, 2020 12:24
@pdobacz
Copy link
Contributor

pdobacz commented Feb 11, 2020

hm, sorry, I could swear I did an approve ✔️ when placing that comment about spender, but it seems I only commented

@kevsul
Copy link
Contributor Author

kevsul commented Feb 11, 2020

hm, sorry, I could swear I did an approve ✔️ when placing that comment about spender, but it seems I only commented

You had approved @pdobacz , but the later commits forced a re-review 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants