Wednesday 15 November 2006

False Sense of Security

OSS can be great... sometimes. Other times it can produce some fairly terrible things, like this (taken from the now defunct GNU.Free project, laughably labeled at a 1.9 release) that only serve to act as security snake-oil:


/**
* Implements the org.apache.log4j.Appender interface to provide a secure
* addition to GNU.FREE logging.

*

* This class creates a chain of Message Digests, so that the every log entry creates a
* digest of itself with the previous entry. Thus altering the log would result in it
* being inconsistent with the digests unless the entire log was edited.
*
* @version 0.1 11 April 2001
* @author Jason Kitcat
* @since 1.6
*/
public class SecureAppender implements Appender {

private String previous_string;
private String name;

public SecureAppender(String previous_val) {

super();
previous_string = previous_val; // prime previous_string val

}

public void doAppend(LoggingEvent le) {
try {
FileWriter out = new FileWriter("erserver.sec.log", true);

out.write(AuthSys.makeDigest(le.message + previous_string) + "\r\n");
out.close();

previous_string = le.message;
} catch (Exception e) {
}
} //EOF doAppend

// other methods removed for clarity
}

Oh dear. Where shall we start? Major points first:

1. The implementation is wrong. You need only alter the digest of the entry you've changed and the subsequent digest. I suspect the doAppend method was meant to look like:

public void doAppend(LoggingEvent le) {
try {
FileWriter out = new FileWriter("erserver.sec.log", true);

string digest = AuthSys.makeDigest(le.message + previous_digest);

out.write(digest + "\r\n");
out.close();

previous_digest = digest;
} catch (Exception e) {
}
} //EOF doAppend


2. The clear text log and the digest log are on the same machine, worse still in the same directory. If the clear text and the digests are on the same machine just forget about it. Anything like this is just wasting CPU cycles.

Minor stuff now:

3. Where the heck do the exceptions go when you can't write the event? Nowhere, which is bad practice in my codebook.

Just give it up. This sort of thing isn't simple, there's no hashing Holy Grail to solve these kinds of problems, the real solutions rely on defense in depth which involves separate logs on separate systems behind layers of security that you can't squeeze a gnat through.

7 comments:

Jason Kitcat said...

Hi Daniel

Yes, 'twas me that wrote this code. Perhaps not the finest code ever though it was reviewed by smart people in out of universities around the world. Quite nostalgic to see some of the Java code again.

I don't actually agree that it is broken. From memory (and the code you cite), the SecureAppender writes a log entry and then creates a hash of the current entry with the previous entry. The previous entry is hashed with the entry before it and so on. The result is that every entry is linked to the one before it and the first entry is a known value.

I'm sure many improvements could be thought of, such as having copies elsewhere. Which really proved my point when I, along with Richard Stallman, agreed that electronic voting was a bad idea and so halted the project. I have been campaigning to stop the introduction of e-voting ever since...

2002 decision to stop work on the project, the announcement offers some background.

My e-voting pages include the paper I wrote on why Open Source isn't the answer to voting system problems, many articles written for LinuxUser about e-voting, analysis of pilots and much more.

The Open Rights Group are co-ordinating action on the 2007 e-voting pilots. The Wiki has more info.

Daniel Gray said...

No really. It is broken. The first implementation doesn't chain the digests, it only chains the second clear text to the previous clear text. My fixed code does what it's supposed to do. And even that is next to useless, since you have the whole of the clear text to rehash.

As to never running eVoting because it's hard. Well, sorry, duh! No one ever said it was going to be easy. To approach a problem of this magnitude and then throw your hands up in the air and give up when it gets difficult is one thing. To say that because you failed no one else can do it something entirely different.

And please, RMS is a great OSS advocate, but he's not an eVoting expert by any stretch of the imagination.

Jason Kitcat said...

Daniel - the digests don't need to be chained because they reflect the log entries which are chained. The procedure for checking the validity of the log files only works with the digest and plain text logs together.

But as you say, the are other bigger issues. Which I agree there were - logging was a serious problem I spent a long time discussing with logging experts including the creator of the log4j library. The problems of log performance, reliability, security, auditability and verifiability are very tricky indeed. The 1.9 version number is a bit wacky considering the unfinished state of the logging system - there was some obscure reason I can't remember anymore why we versioned it like that.

The decision to halt the project wasn't just because it was hard - of course it was hard. The reason was that even if we built as near-perfect a system as possible, there was no way to be sure that it was setup, configured and run in a secure and private way. There are just too many variables.

Also, once I stepped back from the technical perspective, how to convince voters that any 'black box' consisting of opaque technologies is trustworthy is the true issue.

When you look at voting reform in perspective, introducing computer technology to our elections is in many ways a tragedy. It took over 50 years of hard fighting in the UK before the secret Australian paper ballot became permanent in 1882.

RMS is no e-voting expert, but he's an incredibly smart and technically literate man. He is one of thousands of people around the world who actively oppose electronic voting systems, these people are computer scientists, activists, academics, politicians, civil liberties campaigners and so on.

Daniel Gray said...

Sorry having a little difficulty with this one.

The initial state of the class is with a previous_string of "abc".

The logger then appends the message "one" as digest("abc" + "one"). previous_string becomes "one".

The logger then appends the message "two" as digest("one" + "two"). previous_string becomes "two".

The logger then appends the message "three" as digest("two" + "three").
previous_string becomes "three".

If I wanted to change the message "one" to "one1" in the clear text I would then alter the digest log so that digest("abc" + "one") becomes digest("abc" + "one1") and alter digest("one" + "two") to digest("one1" + "two").

The correct (if correct is the right term given the overall security of the method) is:

previous_digest is a known value

Message "one" is to be appended. A digest is produced as digest("one" + previous_digest). The digest is written and becomes previous_digest.

Message "two" is to be appended. A digest is produced as digest("two" + previous_digest). The digest is written and becomes previous_digest.

Message "three" is to be appended. A digest is produced as digest("three" + previous_digest). The digest is written and becomes previous_digest.

Now the digests are chained, such that an alteration at one point requires the changing of the whole log.

This bit worries me, you seem to be changing the specification of the class... "the digests don't need to be chained because they reflect the log entries which are chained" whereas the class comments read "This class creates a chain of Message Digests, so that the every log entry creates a digest of itself with the previous entry". Also the clear text logger is defined in log4j.erserver.properties as a plain RollingFileAppender. So the clear text entires aren't chained and neither (currently) are the digests.

As to the issue of voter trust, voters know that they aren't qualified to understand if something is trustworthy. They'll take the word of someone trustworthy who has inspected and certified the system. And given the nature of the system we're talking about and the possible implications of a security breach, those trustworthy people are going to be from GCHQ, MI5 and beyond.

As to the setup, deployment and running of a system. Well, see above. You have the system certified for use before any voter gets near it.

Finally, RMS. Yes he's a smart guy, yes he's technologically very literate. Has he ever built and had certified a secure system? A bank for example, a trading platform, weapons guidance system, air traffic control system? These all exist and are considered as secure as they can be made. A perfectly secure system (as Schneier has said) is impossible, and the current voting system is NOT perfectly secure either. We've come up with a number of ways of attacking a traditional "secret" (note the use of quotes, elections are not secret in this country, a Judge can find out how you voted if they want to) at work, and I'll be posting about these quite soon.

Jason Kitcat said...

Ah yes, I see your point. Thank you.

Your point on trust seriously worries me though - it is extremely paternalistic and elitist: "voters know that they aren't qualified to understand if something is trustworthy."

Any citizen can and should be able to understand and trust their voting system. Only with collective responsibility and participation does voting have any legitimacy. Elections are run by the people, for the people. Not by government for government. Restricting the verification of a voting system's trustworthiness to GCHQ or MI5 is not good for democracy and opens the door wide for conspiracy theories.

I have never said that the current voting system is perfect in fact I have advocated reform there also. Our numbered ballots (which violate the secrecy of our votes) are an anachronism dating from our borrowing of procedure from an Australian colony which even the rest of Australia chose not to use. The tracking numbers breach human rights law and their time is up.

Bank, weapons guidance or air traffic control systems are in no way as secure as they can be made. Banks are notorious for security problem cover-ups. Ross Anderson at Cambridge is one of many to have shown this. Weapons system also have had numerous problems and I think air traffic control systems have had a enough coverage of their problems to not warrant my providing links.

Let me ask, why do you think we need electronic voting in the UK?

Daniel Gray said...

To be honest elitism wasn't where I was coming from, it was more pragmatic. I'd asked my wife the previous evening whether she would be comfortable voting online in an election and how she would trust the system. Her response was "yes" she would vote online and that she'd trust the system because someone else had verified it. She knows she's not in a position to check these things and it would be a waste of her time to attempt to do so.

As to the numbered ballots, you're kind of contradicting other things you've said there. Without numbered ballots there can be NO verification that a voters ballot has been counted correctly. So voter verification goes right out of the window if we remove it. Which is it: total anonymity or verification? Chose one.

I take your point that these systems are not, in every case, secure. But do the problems associated with one or two systems mean that we shouldn't ever try anything better, much less use them. Tell me, do you use ATMs? Fly in a plane, feel protected by our military? If so you're putting trust in those systems and those who have verified them. Chains of trust are an intrinsic part of our soceity, it is impossible for every individual to verify every system and interaction that they have. Could you imagine if schools couldn't perform CRB checks (again not perfect), but rather had to trawl through individuals history themselves? Totally impractical I think you will agree. Also who verifies a paper ballot? The people present must be trusted by the voters surely? So unless we remove that chain from the current voting system we must reasonably acknowledge that there are people who are trusted who check the election.

Finally, why do we need electronic voting? Verification scales significatly better in an eletronic system, could you imagine if all the millions of voters demanded to check that their ballot was counted correctly? How much judicial and local authority time would be eaten by that?

People expect, in our technology based society, to be able to vote electronically. I have a number (of admittedly young) colleagues who refused to vote until they can do so electronically (I know, I know I've argued the point with them many times, but their immovable on this). Almost everyone I've spoken to under a certain age (around mid 30s) considers the current paper ballot archaic and INSECURE (yes you put your ballot in the box, but what's in the box? A shredder, a false bottom, a pool of acid? How do I know the box I put my vote in made it to the counting station, is every ballot box accompanied by a witness at all times?

Next there's accessibility, if you're blind I believe you need to cast your vote via a proxy. Electronic systems that have been properly designed can provide a much more usable experience.

Finally, convience. What if I'm away from my local area on polling day? Due to an unavoidable business meeting for example? Currently I can't vote unless I'm able to make it back in time to vote where I'm registered. And since you're opposed to postal votes I can't do it that way either.

Anonymous said...

Hi Daniel,

I work at a not for profit organisation that is using GNU.Free for some internal purposes. Some of the more technically savvy people here have raised some concerns about the way the system works, and some of the coding. Apparently the software hasn't really been verified by anyone, and your recent post (pointed out to me by a co-worker that reads the Daily WTF) concerning the SecureAppender class has only heightened some peoples concerns. We were wondering if you could have a further look into the codebase for this project and see what else you can find?

Thanks

Ben