monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] WARNING: ~/.monotone/keys CONSIDERED HARMFUL


From: Brian May
Subject: Re: [Monotone-devel] WARNING: ~/.monotone/keys CONSIDERED HARMFUL
Date: Thu, 30 Oct 2008 11:24:40 +1100
User-agent: Thunderbird 2.0.0.17 (X11/20080925)

Daniel Carrera wrote:
Depending on what you mean by identify. If you are happy with:

Matz <address@hidden> (Real name withheld)


Then I agree. You don't care what Matz' real name is, as long as you know that this patch was signed by the guy who uses the handle Matz on the list and whom you trust.

Yes, agreed.

///The problem is there is no security in mapping the key to the keyid. If I look at the output of / "ls certs <revision>" and see that it was signed by "/address@hidden" how do I know it was signed by keyid e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6? I don't. More importantly, how do I know it really was signed by /"/address@hidden"? I don't.

I understand. The system should (and currently does) do access control based on the keyid (e17e2bdd17...) regardless of what name the key claims to correspond to. If someone uploads e17e2bdd17... to the server and I (evil cracker) make another key (2f0399e...) claiming to be Brian, the server won't trust me.
From <http://www.monotone.ca/docs/Basic-Network-Service.html>:

$ cat >>~/.monotone/read-permissions

pattern "*"
allow "address@hidden"
allow "address@hidden"
^D

$ cat >>~/.monotone/write-permissions
address@hidden
address@hidden
^D


Doesn't look like key hashes to me...
As far as I am aware, there is nothing to stop an attacker changing the mappings in the database, to look like, maybe:

If anyone with write access can insert a new trusted key, that is a security hole. But at this point, it doesn't matter if the key says Brian or Dr. Evil. The guy is in.

I think that is a valid argument. If you assume all keys in the database are trusted, and make sure keys can't be added unless trusted, I guess there shouldn't be a problem.

Just because X trusts a given key, and you are syncing from X, or X is syncing to you, does this mean you automatically trust the key too?

Now everything that was signed by key e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 will look like it was signed by address@hidden, and everything that appears to be signed by "address@hidden" is actually signed by a key that only the attacker was the corresponding private key.


What kind of access do you need to mount this attack?

Access to the database. Or ability to trick somebody to sync from you. Easy if they are starting from an empty database.

And now when you sync to the central server everyone gets the changes too? That's a serious attack. Do some damage and frame another developer (e.g. a co-worker you don't like).
[...]
I guess we can't ask you to sync with the server :-) But you could setup a local server with a copy of the good database and see what happens when you sync with it.


Well my first attempt didn't work very well.

file:///home/brian/website-wiki.mtn is the good copy, checked out in ~/a/au.com.microcomaustralia.wiki file:///home/brian/monotone/website-wiki.mtn is the bad copy, checked out in ~/au.com.microcomaustralia.wiki

=== cut ===
address@hidden:~/au.com.microcomaustralia.wiki$ mtn sync file:///home/brian/website-wiki.mtn "*"
mtn: connecting to file:///home/brian/website-wiki.mtn
mtn: finding items to synchronize:
mtn: certificates | keys | revisions
mtn:          402 |    4 |       134
mtn:  bytes in | bytes out | revs in | revs out
mtn:     7.2 k |     3.3 k |       0 |        0
mtn: error: wanted 1 rows got 0 in query: SELECT id, keydata FROM public_keys WHERE hash = ?
=== cut ===

I don't understand what is going on here. If it can't find the key, why isn't it syncing it?

===  sql statements ===
mtn: 1 executions of BEGIN EXCLUSIVE
mtn: 1 executions of ROLLBACK
mtn: 1 executions of SELECT 1 FROM heights LIMIT 1
mtn: 1 executions of SELECT 1 FROM manifests LIMIT 1
mtn: 1 executions of SELECT 1 FROM revisions LIMIT 1
mtn: 1 executions of SELECT 1 FROM rosters LIMIT 1
mtn: 1 executions of SELECT DISTINCT value FROM revision_certs WHERE name = ?
mtn: 1 executions of SELECT branch, epoch FROM branch_epochs
mtn: 1 executions of SELECT hash, id, keypair FROM 'revision_certs' WHERE name != 'branch'
mtn: 4 executions of SELECT id FROM public_keys WHERE id = ?
mtn: 1 executions of SELECT id, keydata FROM public_keys WHERE hash = ?
mtn: 1 executions of SELECT id, name, value, keypair, signature FROM revision_certs WHERE name = ? AND value = ?
mtn: 4 executions of SELECT keydata FROM public_keys WHERE id = ?
mtn: 1 executions of SELECT parent,child FROM revision_ancestry
mtn: prepared statement ROLLBACK
mtn: binding 0 parameters for ROLLBACK
mtn: statement cache statistics
mtn: prepared 15 statements
mtn: 1 executions of BEGIN EXCLUSIVE
mtn: 1 executions of ROLLBACK
mtn: 1 executions of SELECT 1 FROM heights LIMIT 1
mtn: 1 executions of SELECT 1 FROM manifests LIMIT 1
mtn: 1 executions of SELECT 1 FROM revisions LIMIT 1
mtn: 1 executions of SELECT 1 FROM rosters LIMIT 1
mtn: 1 executions of SELECT DISTINCT value FROM revision_certs WHERE name = ?
mtn: 1 executions of SELECT branch, epoch FROM branch_epochs
mtn: 3 executions of SELECT domain, name, value FROM db_vars
mtn: 1 executions of SELECT hash, id, keypair FROM 'revision_certs' WHERE name != 'branch'
mtn: 4 executions of SELECT id FROM public_keys WHERE id = ?
mtn: 1 executions of SELECT id, keydata FROM public_keys WHERE hash = ?
mtn: 1 executions of SELECT id, name, value, keypair, signature FROM revision_certs WHERE name = ? AND value = ?
mtn: 4 executions of SELECT keydata FROM public_keys WHERE id = ?
mtn: 1 executions of SELECT parent,child FROM revision_ancestry
mtn: error: wanted 1 rows got 0 in query: SELECT id, keydata FROM public_keys WHERE hash = ?
===

It would be good if I could get the above SQL with the ? filled in. It is also not clear to me which database it is looking at.

I don't understand why it is failing here, I can't see any key hash that exists in one database but not the other (I also moved ~/.monotone away just to be sure). I would like to know what hash it is looking for.


address@hidden:~/au.com.microcomaustralia.wiki$ sqlite3  ~/website-wiki.mtn
SQLite version 3.3.8
Enter ".help" for instructions
sqlite> .dump public_keys
BEGIN TRANSACTION;
CREATE TABLE public_keys
   (
   hash not null unique,   -- hash of remaining fields separated by ":"
   id primary key,         -- key identifier chosen by user
   keydata not null        -- RSA public params
   );
INSERT INTO "public_keys" VALUES(X'1C5099967954A7ACEBEBD2EE7BBF4ABD2F35E01F', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D00308189028181009A26A7E43E0E3218DE6FC1AA48FCD22F31928695449B4D712E5EAC420248AF374143A9F27D6406F758E7B103DBE5D40232D91ACFF8FC72C719B4E03D010410017931F7F915D4AADDFC220FE8844D3BDE2108D58B5D5ECBF3CE555B36517B7B5C3B92BC859BED0A64C13F554838A5D8FC34B7F89F02AC7CE2280F2B6749251EE90203010001'); INSERT INTO "public_keys" VALUES(X'D22A65C6ED5D212EC319ACBBB3A9012123928899', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D0030818902818100C65679E8F852BA66226C66BA2A87DA25761AC18129815174B34DE14FA5E93D951F51950A8335BA2A314308414E1129E58E92EBF826B049CD602A83EE55CAF8C9EEF2C95B4C2AED5FD41329315859DDE8142474491346C3A759C23C0FCEF73DD4745F62A189BA375578E5B373195358E14744F8DEBE6CD81FBA13401F3B6CC7C30203010001'); INSERT INTO "public_keys" VALUES(X'E17E2BDD1721AD25F2C439A6E7DF12D8B6F141B6', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D0030818902818100A1B79A84D5FFC20B3ECF19D756C991D0614618C748FA9AA5D423CE73B80D184FD9FE033005BC9B7E6A3110B5D38F3CFABEA3D8A34192820D1D5481465755BB93E65F9A932C119480B8E519B472B4716DEA35719F96B56C75A4DAAAD8EE7357919D1A88A204B2B773F5C341E9246D73E5955DDAA1D55DCB799D22957B26ACDCBB0203010001'); INSERT INTO "public_keys" VALUES(X'A7C3DEEF8F1005230BE3E216ACC052D473FEA994', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D00308189028181009927DDCB757E635A0FD53495FDAA9299799446C64E651C785DC804EFF9310E0837F77EA83274CCC63F92E1D70D1D0D52FF73EE83FDEE7C852E9FA833E12AF6A9C4B19628D041A8AD66C8E9D76B6A54685248D1F2808233DF69A31A046B98584225C04CF672827EA1773D6415170722ECE6DD5597FF56ACA8C23D9EF1E32EBC6D0203010001');
COMMIT;

address@hidden:~/au.com.microcomaustralia.wiki$ sqlite3 ~/monotone/website-wiki.mtn
SQLite version 3.3.8
Enter ".help" for instructions
sqlite> .dump public_keys
BEGIN TRANSACTION;
CREATE TABLE public_keys
   (
   hash not null unique,   -- hash of remaining fields separated by ":"
   id primary key,         -- key identifier chosen by user
   keydata not null        -- RSA public params
   );
INSERT INTO "public_keys" VALUES(X'1C5099967954A7ACEBEBD2EE7BBF4ABD2F35E01F', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D00308189028181009A26A7E43E0E3218DE6FC1AA48FCD22F31928695449B4D712E5EAC420248AF374143A9F27D6406F758E7B103DBE5D40232D91ACFF8FC72C719B4E03D010410017931F7F915D4AADDFC220FE8844D3BDE2108D58B5D5ECBF3CE555B36517B7B5C3B92BC859BED0A64C13F554838A5D8FC34B7F89F02AC7CE2280F2B6749251EE90203010001'); INSERT INTO "public_keys" VALUES(X'D22A65C6ED5D212EC319ACBBB3A9012123928899', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D0030818902818100C65679E8F852BA66226C66BA2A87DA25761AC18129815174B34DE14FA5E93D951F51950A8335BA2A314308414E1129E58E92EBF826B049CD602A83EE55CAF8C9EEF2C95B4C2AED5FD41329315859DDE8142474491346C3A759C23C0FCEF73DD4745F62A189BA375578E5B373195358E14744F8DEBE6CD81FBA13401F3B6CC7C30203010001'); INSERT INTO "public_keys" VALUES(X'E17E2BDD1721AD25F2C439A6E7DF12D8B6F141B6', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D0030818902818100A1B79A84D5FFC20B3ECF19D756C991D0614618C748FA9AA5D423CE73B80D184FD9FE033005BC9B7E6A3110B5D38F3CFABEA3D8A34192820D1D5481465755BB93E65F9A932C119480B8E519B472B4716DEA35719F96B56C75A4DAAAD8EE7357919D1A88A204B2B773F5C341E9246D73E5955DDAA1D55DCB799D22957B26ACDCBB0203010001'); INSERT INTO "public_keys" VALUES(X'A7C3DEEF8F1005230BE3E216ACC052D473FEA994', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D00308189028181009927DDCB757E635A0FD53495FDAA9299799446C64E651C785DC804EFF9310E0837F77EA83274CCC63F92E1D70D1D0D52FF73EE83FDEE7C852E9FA833E12AF6A9C4B19628D041A8AD66C8E9D76B6A54685248D1F2808233DF69A31A046B98584225C04CF672827EA1773D6415170722ECE6DD5597FF56ACA8C23D9EF1E32EBC6D0203010001');
COMMIT;

Brian May




reply via email to

[Prev in Thread] Current Thread [Next in Thread]