| I believe there are things to learn from reviewing the FitNesse source code. I once looked at FitNesse as an example of TDD. I was, and am, doubtful of that technique as an improved method for good design. I found a number of security holes. For example, the "files" resource was open to arbitrary directory traversal, so I could download any file on the system. (I reported it. It has since been fixed.) One of the files I could download was the configuration file. It contains a hashed password, but the hash algorithm was trivial to break. Within a couple of hours I had a program which would generate a string that generates the same hash value. (This does not appear to have changed.) Schneier once wrote "There are two types of encryption: one that will prevent your sister from reading your diary and one that will prevent your government." The fitnesse.authentication.HashingCipher is of the first type, which is likely good enough for the purpose. However, something like <salt>+MD5 would be at least equally secure, shorter, and easier for others to understand. Once I had a password to upload a file, there was another directory traversal error which would let me place a file anywhere on the file system. (This has since been fixed.) There are still design errors. For example, to delete the file "foo.txt", do a GET request to http://localhost:8080/files?responder=deleteFile&filename=fo... . While FitNesse itself uses a POST, the handler can take a POST or a GET. This would easily allow someone to construct a malicious page which secretly wipes things from your server. If you are Martin then don't follow this link: http://fitnesse.org/files?responder=deleteFile&filename=head... ;) It's also still open to cross-site scripting. For example, http://localhost:8080/files?responder=%3Cscript%3Ealert%28%2... gives a "hi!" alert. Thus, if I can get a FitNesse admin to click on a well-crafted link then I can deface the site. My conclusion was that TDD doesn't lead to any better security design than a non-TDD project. If your production code requires security then TDD isn't enough. My question to TDD people is: what other design techniques should one use in order to have a secure design? So far I haven't gotten an answer. I also noticed any number of places where the server, which claims to be an HTTP/1.1 server, doesn't actually follow the HTTP specification. For example, FitNesse does not include a "Date" header in the response, but section 14.18 of the spec says "Origin servers MUST include a Date header field in all responses, except in these cases", none of which include FitNesse. More esoteric, 5.1.2 of the spec says "all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies", but FitNesse assumes the first character of the Request-URI is a "/", so accepts "GET $ HTTP/1.0" as a valid request line. These are not critical details, and my own HTTP servers don't follow the details of the spec. For most people, the only important test is that the browsers can understand it. My point here is only the observation that TDD doesn't give a better mechanism to ensure that the software design meets an external specification. |
Strangely, it might be the case that programmers who have used some form of red-green-refactor TDD have realized its shortcomings, and are not eager to present that publicly, and also recognize that it cant be set in stone as the one true method to write correct code.
Maybe its time I stopped trying to research more about TDD, and just conclude that what works for writing correct programs is what has always been the workflow:
1. Spend time analyzing the problem.
2. Come up with an algorithm based on similar problems or something that makes sense to the programmer.
3. Ensure that there are tests to verify it.
4. Implement the algorithm(s).
5. Change code and tests iteratively based on more analysis.