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

Insufficient htlc_extend_operation validation #1696

Closed
abitmore opened this issue Apr 4, 2019 · 10 comments

Comments

Projects
None yet
4 participants
@abitmore
Copy link
Member

commented Apr 4, 2019

Bug Description

  1. Everyone can extend a HTLC, which means funds inside can be locked forever (although need to pay per-day fee).

    void_result htlc_extend_evaluator::do_evaluate(const htlc_extend_operation& o)
    {
    htlc_obj = &db().get<htlc_object>(o.htlc_id);
    return void_result();
    }

  2. Theoretically the sender can overflow a HTLC and got refunded (although may need to pay a large per-day fee).

    void_result htlc_extend_evaluator::do_apply(const htlc_extend_operation& o)
    {
    db().modify(*htlc_obj, [&o](htlc_object& db_obj) {
    db_obj.conditions.time_lock.expiration += o.seconds_to_add;
    });
    return void_result();
    }

Impacts
Describe which portion(s) of BitShares Core may be impacted by this bug. Please tick at least one box.

  • API (the application programming interface)
  • Build (the build process or something prior to compiled code)
  • CLI (the command line wallet)
  • Deployment (the deployment process after building such as Docker, Travis, etc.)
  • DEX (the Decentralized EXchange, market engine, etc.)
  • P2P (the peer-to-peer network for transaction/block propagation)
  • Performance (system or user efficiency, etc.)
  • Protocol (the blockchain logic, consensus, validation, etc.)
  • Security (the security of system or user data, etc.)
  • UX (the User Experience)
  • Other (please add below)

CORE TEAM TASK LIST

  • Evaluate / Prioritize Bug Report
  • Refine User Stories / Requirements
  • Define Test Cases
  • Design / Develop Solution
  • Perform QA/Testing
  • Update Documentation
@xeroc

This comment has been minimized.

Copy link
Member

commented Apr 4, 2019

Related, the fee_payer for that operation:

*/
account_id_type fee_payer()const { return update_issuer; }

with no check if the update_issuer has to do with the HLTC, at all.

The question is whether this is a bug or a feature.

@pmconrad

This comment has been minimized.

Copy link
Contributor

commented Apr 4, 2019

This is clearly a bug. BSIP-44 specifies checks on both update_issuer and time:

transaction_obj htlc_extend(id, issuer, timeout_threshold, broadcast)
Validate: 'issuer' = get_htlc(id).from
Validate: timeout_threshold < now() + GRAPHENE_HTLC_MAXIMUM_DURRATION

How the hell did we miss that?

@abitmore

This comment has been minimized.

Copy link
Member Author

commented Apr 4, 2019

By the way, the fee_payer in htlc_redeem_operation is not validated as well, however the funds will be sent to the to account of the HTLC object, so it's not a big deal.

void_result htlc_redeem_evaluator::do_evaluate(const htlc_redeem_operation& o)
{
htlc_obj = &db().get<htlc_object>(o.htlc_id);
FC_ASSERT(o.preimage.size() == htlc_obj->conditions.hash_lock.preimage_size, "Preimage size mismatch.");
const htlc_redeem_visitor vtor( o.preimage );
FC_ASSERT( htlc_obj->conditions.hash_lock.preimage_hash.visit( vtor ), "Provided preimage does not generate correct hash.");
return void_result();
}
void_result htlc_redeem_evaluator::do_apply(const htlc_redeem_operation& o)
{
db().adjust_balance(htlc_obj->transfer.to, asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id) );
// notify related parties
htlc_redeemed_operation virt_op( htlc_obj->id, htlc_obj->transfer.from, htlc_obj->transfer.to,
asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id ) );
db().push_applied_operation( virt_op );
db().remove(*htlc_obj);
return void_result();
}

An issue related to this is:

void operator()( const htlc_redeem_operation& op )
{
_impacted.insert( op.fee_payer() );
}
void operator()( const htlc_redeemed_operation& op )
{
_impacted.insert( op.from );
}

which means the real to account won't be notified when the redemption is done by a 3rd party.

@jmjatlanta jmjatlanta self-assigned this Apr 4, 2019

@jmjatlanta

This comment has been minimized.

Copy link
Contributor

commented Apr 4, 2019

As for htlc_redeem: I cannot think of a scenario where it would be advantageous to allow someone else to execute an HTLC. I think we should validate that the redeemer is the "from".

If someone can think of a scenario, then we can conditionally add "to" to the _impacted collection.

I do not feel this redeem issue is urgent. I await the opinions of others.

@abitmore

This comment has been minimized.

Copy link
Member Author

commented Apr 4, 2019

@jmjatlanta in the scenario: A initialized a HTLC to transfer to B, C redeemed, get_account_history of A contains a create and a redeemed, history of B contains only a create, history of C contains only a redeem. It would be a bit strange that B doesn't have a history entry while the balance increased.

Actually, if we can prevent another account from redeeming the HTLC, this issue would be gone. That said, we should validate that the redeemer is the "to".

@jmjatlanta

This comment has been minimized.

Copy link
Contributor

commented Apr 4, 2019

Actually, if we can prevent another account from redeeming the HTLC, this issue would be gone. That said, we should validate that the redeemer is the "to".

Done as part of #1699. Please take a look.

@pmconrad

This comment has been minimized.

Copy link
Contributor

commented Apr 5, 2019

https://github.com/bitshares/bsips/blob/master/bsip-0044.md#redeem specifies that

// NOTE: any account may attempt to redeem

IMO the correct fix is to include htlc_redeemed_operation also in the history of to.

@jmjatlanta

This comment has been minimized.

Copy link
Contributor

commented Apr 5, 2019

IMO the correct fix is to include htlc_redeemed_operation also in the history of to.

I guess we should follow the spec. #1699 updated.

@abitmore

This comment has been minimized.

Copy link
Member Author

commented Apr 5, 2019

I agree that it's good to follow the spec. However, it means the history object numbering of new code is different than 3.0.0, thus we need to force everyone to upgrade to avoid potential data mismatching issues (which would be messy). So IMHO under the current situation it's easier and more practicable to apply a more strict rule (can be witness-only) even if to is added to impacted of htlc_redeemed_operation until next consensus release.

This was referenced Apr 8, 2019

@abitmore abitmore added this to the 3.0.1 - hotfix milestone Apr 8, 2019

@abitmore

This comment has been minimized.

Copy link
Member Author

commented Apr 10, 2019

Fixed by #1699.

@abitmore abitmore closed this Apr 10, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.