orbitdb: Custom AccessController is not immutable
class CustomAccessController {
static get type() { return 'someUniqId' }
static async create(orbitdb, options = {}) {
return new CustomAccessController(orbitdb, options);
}
async canAppend(entry, identityProvider) {
return true;
}
async load(address) {}
async save() { return {} }
}
AccessControllers.addAccessController({ AccessController: CustomAccessController });
const ipfsOptions = {
repo: 'ipfs/' + 'someUniqId',
config: {
Addresses: {
Swarm: [
'/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star/'
]
}
}
};
const ipfs = await Ipfs.create(ipfsOptions);
const orbitdb = await OrbitDB.createInstance(ipfs, {
AccessControllers: AccessControllers
});
const db = await orbitdb.keyvalue('someUniqId', {
accessController: {
type: CustomAccessController.type,
}
});
await db.load();
await db.put('key', 'value');
Hello, for the sake of understanding, I’ve minified my code a maximum.
With this chunk of Code I’ve successfully added { 'key', 'value' } on the keyValue OrbitDB database called someUniqId.
The issue arises when I create a new OrbitDB database with a new uniq name someUniqId2, that this time I set true to false to the method canAppend
async canAppend(entry, identityProvider) {
return false;
}
The first time I run this code, I get an error since the user is not allowed to update it.
The issue is : If a second user (user number 2) runs after this the same code but with return true instead of return false, he can access and perform the db.puts successfully on the database someUniqId2.
I thought that my CustomAccessController is forever added in a immutable way to my new someUniqId2 database the first time the db gets created. I thought that Custom Access Controllers were created as to define forever during the creation of the databases the rules set ? Is my understanding incorrect ? How can user number 2 overrides the custom access controller rules and managed to propagates the put entry to OrbitDB/IPFS ? Been struggling a day with this issue.
In my real code (not this simplified version), I’ve set complex rules. 4 first append gets accepted. The fifth one gets refused. But a malicious user just needs to replace the whole canAppend function by return true; to bypass all the verifications.
Thanks
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Comments: 19 (8 by maintainers)
This is what I was expecting. But I can’t replicate this scenario. Can you show me how that works @haydenyoung ?
In my code, firstDb is replicating secondDb’s data. You just need to run the code twice and you’ll see on the second
firstDb.all()that it fetched the violating data.Or you can just run this:
node.mjshttps://gist.github.com/shideneyu/31e77772ec2a14f2746252720efdbd5eWhen writing malicious records to secondDb, check whether firstDb is replicating them. If not, the access controllers should be working as expected and your firstDb should be “protected” from any data being written to secondDb.
There is nothing stopping secondUser from circumventing (for whatever reason) local checks on secondDb. firstUser is not responsible for ensuring the integrity of secondUser’s data. Instead, we want to ensure that firstDb will not replicate secondDb’s data if it is in violation of the rules laid out by the Custom AC.
@shideneyu Like I said in my first comment, that’s every web application ever written.
“Never trust the client” is the first rule of client-server security.
“Never trust a peer” is the first rule of p2p security.
My expectation would be the “good” peer rejects the new data from the “bad” peer, and that “good” peers can know what’s good from the IPFS data, not the code.