radixdlt/radixdlt-js

Application id collisions

0joshuaolson1 opened this issue · 12 comments

From https://www.radixdlt.com/post/introducing-the-radix-javascript-library:

Application id is just a string you choose yourself for your application. There's no guarantee that someone else won't select the same application id, so it's up to you to validate the data you read from the ledger

  • Why do we specifically want a global namespace of manually chosen human-readable non-versioned application id strings?
  • What kinds of Time-Of-Check-To-Time-Of-Use situations might we have to atomically deal with?
  • Is validating my data as simple as being able to decrypt it with an identity?

Because Radix is sharded, it would be expensive to ensure the uniqueness of application ids. You can think of this like a file-system - there's nothing stopping other applications from accessing with your application's files in an operating system.

The application id has to be deterministic, so that your dApp knows what to look for, but it's up to you how you manage that - there's no reason it has to be human-readable, you could use a hash for example.

One part of validation is being able to decrypt the data but the library manages that for you, what you as the developer need to check that the data is in the format you expect - you can store arbitrary strings, you choose the format to match your needs.

Regarding TOCTTOU - you have to watch our when building transactions, because each transaction references and invalidates specific consumables you own, so if you build multiple transactions in parallel you might get a conflict. We will probably provide a higher-level API that helps you avoid that at some future point.

developer need to check that the data is in the format you expect - you can store arbitrary strings

Could there be a way to avoid decrypting and loading/reading an arbitrarily huge string in memory in order to find that it isn't yours?

And what if someone uses the same format? Security issue?

And what if someone uses the same format? Security issue?

I think we're looking at two different things here. The format of the data (say, a JSON structure) is only interesting once the data is decrypted and has as such nothing to do with security. The format check you may need to do, as a developer, is more of an application layer matter; for example what version of the data protocol you're dealing with, if your application deals with multi-versioned data.

The security is guaranteed by the encryption (and the fact that the private key is sufficiently protected). You may very well end up in a situation where someone accidentally has written data to an address in your application domain, maybe even with your application id, but not even here is your data in any way compromised (again: if you have protected your private key sufficiently). The only (theoretical) issue is rather that you may waste clock-cycles on attempting to decrypt something you can't. But if your application is graceful enough, it will only ignore the resulting gibberish and continue with the next item.

Now I see what you're saying. Can't we just make decryption fail?

The library has no way of knowing what's valid and what's invalid data for your application - some might want to store binary data there not json.

The decryption has checks built in that it only works with the right private key, but anyone can encrypt data that your private key can decrypt, they only need your public key - that's how people can send you encrypted messages without your private key.

Let's say an app is open source. If the app id and data format are public, the app developer may have to add a new layer of encryption to prevent arbitrary parties messing with internal state?

Interesting, depends on what you want to do.
One option might be handling encryption yourself, however I don't think it's a good idea in most cases, and it gets real tricky if you want your app to support external private keys in the wallet applications or hardware wallets, as you don't actually get access to them, you can only ask them to perform actions with some piece of data and return a result, and supporting symmetric encryption isn't planned currently.

A better option would be to only take into account the atoms that have been signed by the user - you don't really care what random garbage others can write in your application data as long as you have a good way to filter it. Conversely, I don't think you need to stop other applications from modifying your data if it's done by the same user - it allows for other people to make applications that interact with yours.

The library currently doesn't support such a thing, but it should be fairly easy to add by making your own AccountSystem that works similarly to RadixDataAccountSystem.

I think this might be a common enough use-case that we should support it natively, maybe a more general case where you can filter by accounts which have permissions to write data for your application.

random garbage others can write in your application data

I admit that I know very little about Radix, but would this garbage be automatically replicated? (spam + data storage burden, if you will)

And to reiterate, I think such an AccountSystem should try to mitigate the O(n) burden of decrypting arbitrarily large strings of spam/garbage in the first place.

Yes, kind of - every atom lives in at least one shard, as many as you want really, so it's replicated across all the nodes who serve any of those shards. But whoever creates the atom has to pay a fee proportional to the size of the atom and how many shards it's stored in, so the nodes are happy to oblige.

We're also planning to include free messaging, but that will have limits to minimise abuse.

What @MuncleUscles said (a few comments up). I too am a strong believer in the signature approach. For now you may have to do client-side filtering though (on signature), but I think it's just a matter of time before the client libraries (JS, Java, Kotlin, ...) will expose it too, as a core feature.

Closed since this library is now deprecated.