The Oraclize API allows users to encrypt a query or part of a query using their public key "to protect data from public scrutiny," to quote their documentation.

The documentation has this to say about replay attacks: "In order to prevent other users from using your exact encrypted query ('replay attacks'), the first contract querying Oraclize with a given encrypted query becomes its rightful 'owner.' Any other contract using that exact same string will receive an empty result."

A few points of clarification:

  1. If I send a computation query where an encrypted API token is one of the arguments, and the other arguments are not encrypted, will an attacker be able to use my API token to make computation queries with different plaintext arguments? The documentation refers to "that exact same string" but it's not clear to me whether that refers to a single argument, or the entire query.

  2. If an attacker does attempt a replay attack using "that exact same string," and Oraclize returns an "empty result" to that user, what exactly has happened behind the scenes? Has Oraclize actually executed the query and then just hidden the result to the caller? If so, that is a problem, because most APIs have a request limit, and an attacker could use this to spam the external API and exceed the token request limit, thereby breaking the smart contract. My specific external API has a limit of 5 requests per second and 1000 requests per day, so this isn't too hard to abuse, especially since each computation query will make multiple requests to the external API.

  3. Does the replay attack protection apply to all the networks, or just mainnet? That is, can someone take my encrypted API token from mainnet and use it on Rinkeby to spam the external API and break my smart contract? Or is the "rightful owner" feature consistent across all the networks?

1 Answer 1

  1. Any "decrypt" action will go through owner checks, so it doesn't matter if it's the entire string that's encrypted, partial string, or a single argument, any seen instance, checks the internal db, to see if it has been used before, and if it has, it ensures it's originating from the initial contract address. In summary, anything using Oraclize query decryption will be assigned an owner, and locked to that owner.

  2. If Oraclize returns an empty string, this normally indicates an error somewhere in the pipeline, and the part of the pipeline will be before the actual request is done. The specific error for a replay will normally be: datasources.decrypt.access_denied, which would be visible by checking the query in the engine, or via HTTP API, which is mostly used internally. Example query with an error (processor.query_error) https://api.oraclize.it/v1/query/eth_mainnet_684c58f66467b51e48a9559ee5becf6bd03ef2bc0028ee0fe584bd041a6a3641/status?_pretty=1. So in summary you need not worry about an actual request having been done, if there's a replay, it is preemptively halted at that point and the query resolves with an empty result.

  3. The replay protection is only 100% guaranteed on the mainnet. It supports testnet too, but there's no guarantees that the DBs pertaining to them may not get flushed etc... So in the testnet context, we recommend instead using testing/development keys, that if compromised or replayed wouldn't affect anything serious, and only encrypting production keys for mainnet usage!

  • Sounds good regarding 1 and 2. Regarding 3, what I'm worried about is someone grabbing an encrypted query from mainnet and executing it on a testnet. If an attacker could replay encrypted queries from mainnet on a testnet, they would be able to completely circumvent the encryption, so hopefully that's not possible (haha). Is it?
    – jazzhole
    Commented Jun 26, 2018 at 4:55
  • That should be covered, the point I'm trying to make is if you make a decrypt query on mainnet, it should be locked to that specific contract on mainnet. If someone tries to use it anywhere else it won't work. The same cannot necessarily be guaranteed for a query that originates from testnet, it should, but assume it does not and hence use test keys there.
    – DenisM
    Commented Jun 26, 2018 at 18:36
  • @DenisM now can the end of the encrypted string of a query in a way, it still looks valid and gets decrypted successfully (with modified part of the end decrypting to garbages revealing the first part)? Commented Feb 12, 2021 at 1:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.