Timestamp spoofing by malicious client


Alexandre Pauwels
 

Hey all,
Curious if anyone has put some thought into the consequences of having an unreliable client submit transactions with faked timestamps, and how to mitigate those concerns.

I understand it's an inevitable consequence of needing the transaction input to be constant and determined before reaching the peer, but it does open up some issues with the GetHistoryForKey() shim function. We've tested sending a transaction with a client-provided timestamp that comes before the one provided by the last transaction on that asset, and that function does indeed show the spoofed transaction as having occurred before the the previous transaction. This means a client could, theoretically, manipulate transaction histories as returned by the history shim without any input/checks provided by other parties (although blocks would still be in the correct order, obviously).

My questions are:
1. Are any other aspects of an HLF network affected by a faked timestamp other than the history shim?
2. Are there any mitigating tactics people have used to avoid this problem?

Some of the solutions we've considered are:
1. Loading the current timestamp inside the chaincode at execution time and ensuring the client-provided timestamp is within a certain time range (say, +/- 5 minutes) of the current timestamp. This opens up issues with non-deterministic chaincode as each peer will compare to a different timestamp. Although having a broad enough range should take care of any latency issues, it still poses an issue if one were to replay all transactions and their inputs at a later date. It also would not stop someone from submitting a transaction that appears before the last one as long as the two transactions are received with a gap less than the range.
2. Using a third-party oracle which would provide a "certified" timestamp by signing the transaction with the client-generated timestamp provided that this generated timestamp is within a range of the current time, and then submitting the signed transaction to the peers. Although this makes the chaincode deterministic (just check signature of the oracle), it creates a dependency on a third-party oracle which has to be trusted. We're currently using the node SDK, which may have to be modified to adapt to such a workflow.
3. Check the history of the asset using the shim at chaincode execution-time and check that the most recently committed version's timestamp is not greater than the timestamp provided in the currently executing transaction. This only protects against spoofed timestamps which are before the last transaction, but won't stop someone from providing a past timestamp which is still after the last transaction, and wouldn't stop someone from sending a spoofed timestamp in the future. It also would require iterating through all n previous transactions on that asset as the iterator returned by the history shim always starts at the beginning.

Another potential solution is to allow spoofed timestamps and not deal with them at endorsement time, but to detect them at commit-time and then notify all network participants. This does not stop malicious intent but it does make it obvious to everyone that someone has tried doing something they shouldn't.

Thank you for your time,
Alexandre Pauwels




David Enyeart
 

Fabric intentionally doesn't use the timestamp from the submitting application for anything, therefore there are no impacts with respect to Fabric processing.
The timestamp is not intended to be a reflection of "network time", it can only be as trusted so far as the submitting application is trusted.
Increasing block heights are the only trusted indication of time passage on a blockchain. If applications do reference the timestamp for additional informational context, they should consider it relative to block heights, e.g. are the timestamps increasing as block heights increase, does it make sense relative to the general timeframe of block processing on a peer that your organization trusts?


Dave Enyeart


"Alexandre Pauwels" ---09/04/2019 10:58:54 AM---Hey all, Curious if anyone has put some thought into the consequences of having an

From: "Alexandre Pauwels" <alexj.pauwels@...>
To: fabric@...
Date: 09/04/2019 10:58 AM
Subject: [EXTERNAL] [Hyperledger Fabric] Timestamp spoofing by malicious client
Sent by: fabric@...





Hey all,
Curious if anyone has put some thought into the consequences of having an unreliable client submit transactions with faked timestamps, and how to mitigate those concerns.

I understand it's an inevitable consequence of needing the transaction input to be constant and determined before reaching the peer, but it does open up some issues with the GetHistoryForKey() shim function. We've tested sending a transaction with a client-provided timestamp that comes before the one provided by the last transaction on that asset, and that function does indeed show the spoofed transaction as having occurred before the the previous transaction. This means a client could, theoretically, manipulate transaction histories as returned by the history shim without any input/checks provided by other parties (although blocks would still be in the correct order, obviously).

My questions are:
1. Are any other aspects of an HLF network affected by a faked timestamp other than the history shim?
2. Are there any mitigating tactics people have used to avoid this problem?

Some of the solutions we've considered are:
1. Loading the current timestamp inside the chaincode at execution time and ensuring the client-provided timestamp is within a certain time range (say, +/- 5 minutes) of the current timestamp. This opens up issues with non-deterministic chaincode as each peer will compare to a different timestamp. Although having a broad enough range should take care of any latency issues, it still poses an issue if one were to replay all transactions and their inputs at a later date. It also would not stop someone from submitting a transaction that appears before the last one as long as the two transactions are received with a gap less than the range.
2. Using a third-party oracle which would provide a "certified" timestamp by signing the transaction with the client-generated timestamp provided that this generated timestamp is within a range of the current time, and then submitting the signed transaction to the peers. Although this makes the chaincode deterministic (just check signature of the oracle), it creates a dependency on a third-party oracle which has to be trusted. We're currently using the node SDK, which may have to be modified to adapt to such a workflow.
3. Check the history of the asset using the shim at chaincode execution-time and check that the most recently committed version's timestamp is not greater than the timestamp provided in the currently executing transaction. This only protects against spoofed timestamps which are before the last transaction, but won't stop someone from providing a past timestamp which is still after the last transaction, and wouldn't stop someone from sending a spoofed timestamp in the future. It also would require iterating through all n previous transactions on that asset as the iterator returned by the history shim always starts at the beginning.

Another potential solution is to allow spoofed timestamps and not deal with them at endorsement time, but to detect them at commit-time and then notify all network participants. This does not stop malicious intent but it does make it obvious to everyone that someone has tried doing something they shouldn't.

Thank you for your time,
Alexandre Pauwels







Alexandre Pauwels
 

Hey Dave,
Good to know the timestamp isn't used anywhere else.

However, it is used for determining the order of transactions returned by the GetHistoryForKey iterator, correct? Or at least, in our experience, that has not been ordered by block height, but by the timestamp. This may not be an issue for most people but good thing to be wary of as it may cause non-discerning chaincode to return a transaction as if it happened before another, when in fact it was submitted after.

Alex

On Thu, Sep 5, 2019, 07:30 David Enyeart <enyeart@...> wrote:

Fabric intentionally doesn't use the timestamp from the submitting application for anything, therefore there are no impacts with respect to Fabric processing.
The timestamp is not intended to be a reflection of "network time", it can only be as trusted so far as the submitting application is trusted.
Increasing block heights are the only trusted indication of time passage on a blockchain. If applications do reference the timestamp for additional informational context, they should consider it relative to block heights, e.g. are the timestamps increasing as block heights increase, does it make sense relative to the general timeframe of block processing on a peer that your organization trusts?


Dave Enyeart


"Alexandre Pauwels" ---09/04/2019 10:58:54 AM---Hey all, Curious if anyone has put some thought into the consequences of having an

From: "Alexandre Pauwels" <alexj.pauwels@...>
To: fabric@...
Date: 09/04/2019 10:58 AM
Subject: [EXTERNAL] [Hyperledger Fabric] Timestamp spoofing by malicious client
Sent by: fabric@...





Hey all,
Curious if anyone has put some thought into the consequences of having an unreliable client submit transactions with faked timestamps, and how to mitigate those concerns.

I understand it's an inevitable consequence of needing the transaction input to be constant and determined before reaching the peer, but it does open up some issues with the GetHistoryForKey() shim function. We've tested sending a transaction with a client-provided timestamp that comes before the one provided by the last transaction on that asset, and that function does indeed show the spoofed transaction as having occurred before the the previous transaction. This means a client could, theoretically, manipulate transaction histories as returned by the history shim without any input/checks provided by other parties (although blocks would still be in the correct order, obviously).

My questions are:
1. Are any other aspects of an HLF network affected by a faked timestamp other than the history shim?
2. Are there any mitigating tactics people have used to avoid this problem?

Some of the solutions we've considered are:
1. Loading the current timestamp inside the chaincode at execution time and ensuring the client-provided timestamp is within a certain time range (say, +/- 5 minutes) of the current timestamp. This opens up issues with non-deterministic chaincode as each peer will compare to a different timestamp. Although having a broad enough range should take care of any latency issues, it still poses an issue if one were to replay all transactions and their inputs at a later date. It also would not stop someone from submitting a transaction that appears before the last one as long as the two transactions are received with a gap less than the range.
2. Using a third-party oracle which would provide a "certified" timestamp by signing the transaction with the client-generated timestamp provided that this generated timestamp is within a range of the current time, and then submitting the signed transaction to the peers. Although this makes the chaincode deterministic (just check signature of the oracle), it creates a dependency on a third-party oracle which has to be trusted. We're currently using the node SDK, which may have to be modified to adapt to such a workflow.
3. Check the history of the asset using the shim at chaincode execution-time and check that the most recently committed version's timestamp is not greater than the timestamp provided in the currently executing transaction. This only protects against spoofed timestamps which are before the last transaction, but won't stop someone from providing a past timestamp which is still after the last transaction, and wouldn't stop someone from sending a spoofed timestamp in the future. It also would require iterating through all n previous transactions on that asset as the iterator returned by the history shim always starts at the beginning.

Another potential solution is to allow spoofed timestamps and not deal with them at endorsement time, but to detect them at commit-time and then notify all network participants. This does not stop malicious intent but it does make it obvious to everyone that someone has tried doing something they shouldn't.

Thank you for your time,
Alexandre Pauwels







David Enyeart
 

No, the timestamp has never been used to order results, or in any other regard within Fabric.

There has been a recent improvement in GetHistoryForKey though... this text will appear in the upcoming v2.0 release notes:

FAB-16303 - GetHistoryForKey returns results from newest to oldest
In prior releases, the GetHistoryForKey chaincode API had no
guarantees on the order of returned results.
Starting in Fabric v2.0, the GetHistoryForKey chaincode API
will return results from newest to oldest in terms of ordered transaction
height (block height and transaction height within block).
This will allow applications to iterate through the top results
to understand recent changes to a key.


Dave Enyeart

"Alexandre Pauwels" ---09/05/2019 09:21:59 AM---Hey Dave, Good to know the timestamp isn't used anywhere else.

From: "Alexandre Pauwels" <alexj.pauwels@...>
To: David Enyeart <enyeart@...>
Cc: fabric@...
Date: 09/05/2019 09:21 AM
Subject: [EXTERNAL] Re: [Hyperledger Fabric] Timestamp spoofing by malicious client
Sent by: fabric@...





Hey Dave,
Good to know the timestamp isn't used anywhere else.

However, it is used for determining the order of transactions returned by the GetHistoryForKey iterator, correct? Or at least, in our experience, that has not been ordered by block height, but by the timestamp. This may not be an issue for most people but good thing to be wary of as it may cause non-discerning chaincode to return a transaction as if it happened before another, when in fact it was submitted after.

Alex

On Thu, Sep 5, 2019, 07:30 David Enyeart <enyeart@...> wrote:
    Fabric intentionally doesn't use the timestamp from the submitting application for anything, therefore there are no impacts with respect to Fabric processing.
    The timestamp is not intended to be a reflection of "network time", it can only be as trusted so far as the submitting application is trusted.
    Increasing block heights are the only trusted indication of time passage on a blockchain. If applications do reference the timestamp for additional informational context, they should consider it relative to block heights, e.g. are the timestamps increasing as block heights increase, does it make sense relative to the general timeframe of block processing on a peer that your organization trusts?


    Dave Enyeart


    "Alexandre Pauwels" ---09/04/2019 10:58:54 AM---Hey all, Curious if anyone has put some thought into the consequences of having an

    From:
    "Alexandre Pauwels" <alexj.pauwels@...>
    To:
    fabric@...
    Date:
    09/04/2019 10:58 AM
    Subject:
    [EXTERNAL] [Hyperledger Fabric] Timestamp spoofing by malicious client
    Sent by:
    fabric@...




    Hey all,
    Curious if anyone has put some thought into the consequences of having an unreliable client submit transactions with faked timestamps, and how to mitigate those concerns.

    I understand it's an inevitable consequence of needing the transaction input to be constant and determined before reaching the peer, but it does open up some issues with the GetHistoryForKey() shim function. We've tested sending a transaction with a client-provided timestamp that comes before the one provided by the last transaction on that asset, and that function does indeed show the spoofed transaction as having occurred before the the previous transaction. This means a client could, theoretically, manipulate transaction histories as returned by the history shim without any input/checks provided by other parties (although blocks would still be in the correct order, obviously).

    My questions are:
    1. Are any other aspects of an HLF network affected by a faked timestamp other than the history shim?
    2. Are there any mitigating tactics people have used to avoid this problem?

    Some of the solutions we've considered are:
    1. Loading the current timestamp inside the chaincode at execution time and ensuring the client-provided timestamp is within a certain time range (say, +/- 5 minutes) of the current timestamp. This opens up issues with non-deterministic chaincode as each peer will compare to a different timestamp. Although having a broad enough range should take care of any latency issues, it still poses an issue if one were to replay all transactions and their inputs at a later date. It also would not stop someone from submitting a transaction that appears before the last one as long as the two transactions are received with a gap less than the range.
    2. Using a third-party oracle which would provide a "certified" timestamp by signing the transaction with the client-generated timestamp provided that this generated timestamp is within a range of the current time, and then submitting the signed transaction to the peers. Although this makes the chaincode deterministic (just check signature of the oracle), it creates a dependency on a third-party oracle which has to be trusted. We're currently using the node SDK, which may have to be modified to adapt to such a workflow.
    3. Check the history of the asset using the shim at chaincode execution-time and check that the most recently committed version's timestamp is not greater than the timestamp provided in the currently executing transaction. This only protects against spoofed timestamps which are before the last transaction, but won't stop someone from providing a past timestamp which is still after the last transaction, and wouldn't stop someone from sending a spoofed timestamp in the future. It also would require iterating through all n previous transactions on that asset as the iterator returned by the history shim always starts at the beginning.

    Another potential solution is to allow spoofed timestamps and not deal with them at endorsement time, but to detect them at commit-time and then notify all network participants. This does not stop malicious intent but it does make it obvious to everyone that someone has tried doing something they shouldn't.

    Thank you for your time,
    Alexandre Pauwels










spivak.a.o@...
 

Hey Alexandre Pauwels.
Not sure that you still interesting timestamps-case in HLF (but may be should be helpful for someone else)
Found some interesting fork of HLF that focused on timestamps here:

https://github.com/aritramitra14/fabric/tree/timefabric

https://uwspace.uwaterloo.ca/bitstream/handle/10012/16784/Mitra_Aritra.pdf

https://svr-sk818-web.cl.cam.ac.uk/keshav/wiki/images/1/1a/Time_Fabric_FAB_21.pdf