Comment On But It Worked in the Demo

We've all been there: all of your test cases worked the night before but when it comes time to run the demo you realize you missed something. In college, I had to write Sub Hunter in assembly and those pesky submarines kept launching missiles after I depth charged them back to hell. The TA didn't notice either. It wasn't until later that I learned about the magic of peer review. Not that fewer bugs sneak across the unit test border, you just feel better because someone else missed the problem too. [expand full text]
« PrevPage 1 | Page 2 | Page 3 | Page 4 | Page 5Next »

Re: But It Worked in the Demo

2007-01-26 09:03 • by D (unregistered)
WTF? Why are there no comments?

Re: But It Worked in the Demo

2007-01-26 09:03 • by ShockedITellYou (unregistered)

Woah. Writing stupid units tests doesn't help you. I'm shocked.

Re: But It Worked in the Demo

2007-01-26 09:09 • by Donkey (unregistered)
Aside from the WTF with the where clause...

I liked the fact that this.authenticated = false; gets called for every record that doesn't match.

Re: But It Worked in the Demo

2007-01-26 09:10 • by Troy McClure (unregistered)
113684 in reply to 113681
D:
WTF? Why are there no comments?


Because the story just got put up minutes ago. Some of us have real work to do. Not me per se - it is Friday after all!

Re: But It Worked in the Demo

2007-01-26 09:11 • by sir_flexalot
I think I actually got dumber when I read this!

Re: But It Worked in the Demo

2007-01-26 09:16 • by :D wonderful comment!!! (unregistered)
113687 in reply to 113685
sir_flexalot:
I think I actually got dumber when I read this!

Re: But It Worked in the Demo

2007-01-26 09:16 • by Gareth (unregistered)
Apparently "Karl", the person in charge of the authentication module, wasn't too good at taking criticism as long as the unit test passed.


So the Real WTF[tm] is that there was only a unit test for successful authentication. All someone had to do was write a test for failed authentication to show Karl where his mistake was.

At least the guy was using unit tests...

Re: But It Worked in the Demo

2007-01-26 09:17 • by Spoe (unregistered)
113689 in reply to 113681
Karl was enlightened only when Christian made sure that "testuser" wasn't the last entry in the database.


Um, wouldn't he have wanted to make sure it was the last record to provide the brick upside the head of illumination?

Re: But It Worked in the Demo

2007-01-26 09:18 • by dumbest forum user probably (unregistered)
113691 in reply to 113685
sir_flexalot:
I think I actually got dumber when I read this!



:D wonderful comment!!! And I got dumber as well, look at what I did with my previous comment :D :D

Re: But It Worked in the Demo

2007-01-26 09:19 • by fennec
113692 in reply to 113689
Spoe:
Karl was enlightened only when Christian made sure that "testuser" wasn't the last entry in the database.


Um, wouldn't he have wanted to make sure it was the last record to provide the brick upside the head of illumination?

You're thinking "make it take as loooong as possible to teach him a lesson" perhaps? Aim higher: If it's not the last entry in the database, then the unit test won't work.

Re: But It Worked in the Demo

2007-01-26 09:19 • by Pon (unregistered)
The REAL WTF is that he's persisting hashes.

Re: But It Worked in the Demo

2007-01-26 09:22 • by Name withheld by request (unregistered)
113694 in reply to 113689
Spoe:
Karl was enlightened only when Christian made sure that "testuser" wasn't the last entry in the database.


Um, wouldn't he have wanted to make sure it was the last record to provide the brick upside the head of illumination?


It wouldn't matter where the test record was, The method will still move though all the records in the table before completing. So it may be more effective to demontrate that the method continues to execute long after Authenticated is set to True.

BTW: Nice shiney new captcha

Re: But It Worked in the Demo

2007-01-26 09:26 • by res2 (unregistered)
113695 in reply to 113694
Name withheld by request:
Spoe:
Karl was enlightened only when Christian made sure that "testuser" wasn't the last entry in the database.


Um, wouldn't he have wanted to make sure it was the last record to provide the brick upside the head of illumination?


It wouldn't matter where the test record was, The method will still move though all the records in the table before completing. So it may be more effective to demontrate that the method continues to execute long after Authenticated is set to True.

BTW: Nice shiney new captcha


Actually it does matter, if a match is found before the end, the next loop through would set Authenticated back to false. The only user who could get in would be the last one in the database.

Re: But It Worked in the Demo

2007-01-26 09:41 • by Aaron (unregistered)
The Real WTF™®? is that he didn't use a salt.

Re: But It Worked in the Demo

2007-01-26 09:46 • by imma (unregistered)
113700 in reply to 113694
The problem isn't so much the speed ...
It's that only the last person in the table can log in at all
- imma

Re: But It Worked in the Demo

2007-01-26 09:47 • by kay (unregistered)
Haha. I almost missed that error as well.

Just scanning over the code, it didn't immediately jump out that something was wrong.

It wasn't until the author mentioned that the test was seveal orders of magnitude slower with 10k users, that I realized what was up.

So I don't blame him for missing it as well... he probably coded the function quickly, without much sleep, on a deadline and trusted the test cases to be functional---i.e. test for all scenarios, not just one!

Re: But It Worked in the Demo

2007-01-26 09:50 • by Da' Man (unregistered)
Would adding a WHERE clause suffice? I actually don't like the "SELECT * FROM" either.

What if, in it's next incarnation, the users table also includes user images (BLOB), copies of the user's id card (another BLOB) and a 500-page novel the user was writing while waiting for authentification.

I would actually use sth. like:
SELECT passhash, fullname, rights FROM users WHERE login = 'xympflegrümpf';

and only then check if the password hash matches.

BTW: I give that bloke one thumb up for using hashes rather than sending plain passwords over the network (you don't see that kind of good thinking so often, believe me!)

Re: But It Worked in the Demo

2007-01-26 09:51 • by Disgruntled DBA
113704 in reply to 113700
imma:
The problem isn't so much the speed ...
It's that only the last person in the table can log in at all
- imma


It's worse than that. Assuming they are using SQL Server, when the server has many people logging in, then SQL Server will switch to merry-go-round scans of the users table, and each person may end up with a different "last" record. Nothing like a random output wrapped in a race condition. Yummy.

Re: But It Worked in the Demo

2007-01-26 10:00 • by Troy McClure (unregistered)
113708 in reply to 113698
Aaron:
The Real WTF™®? is that he didn't use a salt.


He's trying to keep his cholesterol down

Re: But It Worked in the Demo

2007-01-26 10:01 • by anon (unregistered)
113709 in reply to 113693
Pon:
The REAL WTF is that he's persisting hashes.


Persisting hashes of the password is a good thing (it's a bad practice to store raw passwords).

Re: But It Worked in the Demo

2007-01-26 10:01 • by J (unregistered)
113710 in reply to 113703
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.

Re: But It Worked in the Demo

2007-01-26 10:03 • by SnapShot (unregistered)
113712 in reply to 113693
Pon:
The REAL WTF is that he's persisting hashes.


Why's that? I persist hashes instead of the plaintext password all the time. But I'd be interested to know why that's not recommended (other than the inability to email passwords to the user if they forget theirs; I generally generate a new random password instead.)

Re: But It Worked in the Demo

2007-01-26 10:05 • by blaaaaaaaaaaaaa (unregistered)
Damn. Bait and switch. I came hungry enough for a smorgasbord and only got an amuse bouche.

Re: But It Worked in the Demo

2007-01-26 10:09 • by J (unregistered)
113715 in reply to 113712
SnapShot:
Pon:
The REAL WTF is that he's persisting hashes.


Why's that? I persist hashes instead of the plaintext password all the time. But I'd be interested to know why that's not recommended (other than the inability to email passwords to the user if they forget theirs; I generally generate a new random password instead.)


Ditto to that. I never store the actual password, and I get quite upset with organizations that do. Especially when they have some random idiot in a call center asking me to repeat my password over the phone to them to verify who I am! WhyTF are they allowed to see it! WhoTF's bright idea was that!

Re: But It Worked in the Demo

2007-01-26 10:09 • by Kiss me, I'm Polish (unregistered)
I must admit I was looking for code like
if (struser == "testuser")

{
this.authenticated = true;
}

But it's so rich! Here we go - misused SELECT, no WHERE clause, just plain wrong true/false setting.
The only positive thing is that it is not SQL injection prone. But I think that's just an accident.
Someone buy this guy a book.

Re: But It Worked in the Demo

2007-01-26 10:10 • by AT (unregistered)
113718 in reply to 113710
J:
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.


Do you think that makes the system more secure? You do realize that the hashed password already must go from the user's computer to the Web server, then from the Web server to the database right?

Re: But It Worked in the Demo

2007-01-26 10:14 • by snoofle (unregistered)
113719 in reply to 113688
Gareth:
Apparently "Karl", the person in charge of the authentication module, wasn't too good at taking criticism as long as the unit test passed.


So the Real WTF[tm] is that there was only a unit test for successful authentication. All someone had to do was write a test for failed authentication to show Karl where his mistake was.

At least the guy was using unit tests...

How would a test for failed authentication have illustrated a missing where-clause in this case?

Re: But It Worked in the Demo

2007-01-26 10:18 • by snoofle (unregistered)
113722 in reply to 113719
snoofle:
Gareth:
Apparently "Karl", the person in charge of the authentication module, wasn't too good at taking criticism as long as the unit test passed.


So the Real WTF[tm] is that there was only a unit test for successful authentication. All someone had to do was write a test for failed authentication to show Karl where his mistake was.

At least the guy was using unit tests...

How would a test for failed authentication have illustrated a missing where-clause in this case?

Nuts - forgot to sign in - can't edit...(captcha = burned... hmmm...)
I meant in the case with only one user in the table...

Re: But It Worked in the Demo

2007-01-26 10:20 • by J (unregistered)
113723 in reply to 113718
AT:
J:
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.


Do you think that makes the system more secure? You do realize that the hashed password already must go from the user's computer to the Web server, then from the Web server to the database right?


Do you think it makes the system less secure? What if the user enters the wrong password? What if the username isn't even valid? Why send the correct password back to the web server when it can do the check at the database?

Re: But It Worked in the Demo

2007-01-26 10:23 • by Rafael Larios (unregistered)
113725 in reply to 113719

if he fails in a simple authenthication process i don't really want to know what the rest of his code would be.....

Re: But It Worked in the Demo

2007-01-26 10:25 • by felix (unregistered)
113726 in reply to 113715
J:
SnapShot:
Pon:
The REAL WTF is that he's persisting hashes.


Why's that? I persist hashes instead of the plaintext password all the time. But I'd be interested to know why that's not recommended (other than the inability to email passwords to the user if they forget theirs; I generally generate a new random password instead.)


Ditto to that. I never store the actual password, and I get quite upset with organizations that do. Especially when they have some random idiot in a call center asking me to repeat my password over the phone to them to verify who I am! WhyTF are they allowed to see it! WhoTF's bright idea was that!


There are password authentication schemes that store the password in plaintext so that the secret must never travel unencrypted over the wire. CRAM-MD5 [RFC 2195] for example. Can come handy if no TLS is in place. It's all about tradeoffs.

Making this information available to a call center agent is wholly different WTF though.

fg

CAPTCHA: Tacos. Tasty, just had some.

Re: But It Worked in the Demo

2007-01-26 10:26 • by Mee (unregistered)
113727 in reply to 113701
Just scanning over the code, it didn't immediately jump out that something was wrong.

Jesus...

Re: But It Worked in the Demo

2007-01-26 10:27 • by hk0
113728 in reply to 113687
Wonderful reply. Excellent commenter. Would read again! A++++!!!!

Re: But It Worked in the Demo

2007-01-26 10:27 • by Ice^^Heat
Damn,

50% of the WTF's out there concern the WHERE clause don't they???!

Re: But It Worked in the Demo

2007-01-26 10:28 • by Fredric (unregistered)
113730 in reply to 113723
J:
AT:
J:
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.


Do you think that makes the system more secure? You do realize that the hashed password already must go from the user's computer to the Web server, then from the Web server to the database right?


Do you think it makes the system less secure? What if the user enters the wrong password? What if the username isn't even valid? Why send the correct password back to the web server when it can do the check at the database?


I would as well go for a stored proc, it's definitely more secure because you don't have to send the correct password anywhere.

The way this code handles it, by sending all users and their password to the client is just about the worst security you can have...

captcha: waffles. Oh great, now I feel like eating some...

Re: But It Worked in the Demo

2007-01-26 10:37 • by Rank Amateur
While being entirely unable to login represents some inconvenience for the typical user, this implementation is preferred because of the superior security. A hacker can’t just guess anyone’s password. It has to be the password of the last user in the table. You can’t have security without some cost to usability.
--Rank

Re: But It Worked in the Demo

2007-01-26 10:38 • by Pon (unregistered)
113733 in reply to 113726
felix:
J:
SnapShot:
Pon:
The REAL WTF is that he's persisting hashes.


Why's that? I persist hashes instead of the plaintext password all the time. But I'd be interested to know why that's not recommended (other than the inability to email passwords to the user if they forget theirs; I generally generate a new random password instead.)


Ditto to that. I never store the actual password, and I get quite upset with organizations that do. Especially when they have some random idiot in a call center asking me to repeat my password over the phone to them to verify who I am! WhyTF are they allowed to see it! WhoTF's bright idea was that!


There are password authentication schemes that store the password in plaintext so that the secret must never travel unencrypted over the wire. CRAM-MD5 [RFC 2195] for example. Can come handy if no TLS is in place. It's all about tradeoffs.

Making this information available to a call center agent is wholly different WTF though.

fg

CAPTCHA: Tacos. Tasty, just had some.


Sorry, I should have been more specific. If they are just using something like "pass.GetHashCode()" for the hash, then that is not guaranteed to stay the same in future versions of the framework. Therefore, no user will be able to log in. If, however, they are using a fixed algorithm, like MD5, then that's fine.

Re: But It Worked in the Demo

2007-01-26 10:39 • by Anonymous Coward (unregistered)
113734 in reply to 113729
Ice^^Heat:
Damn,

50% of the WTF's out there concern the WHERE clause don't they???!


At least that one was resistant to SQL injection... ;-)

Re: But It Worked in the Demo

2007-01-26 10:46 • by Sue B
I was on-site when a report just would not finish. The customer had a lot of data. The report worked "fine" without a lot of data.

The culprit we were reading a table without a where clause. Upon further inspection we never used any data from table. DOH!

Deleted the whole SQL statement and amazed the customer.

Re: But It Worked in the Demo

2007-01-26 10:49 • by fmobus
113736 in reply to 113730
Fredric:
J:
AT:
J:
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.


Do you think that makes the system more secure? You do realize that the hashed password already must go from the user's computer to the Web server, then from the Web server to the database right?


Do you think it makes the system less secure? What if the user enters the wrong password? What if the username isn't even valid? Why send the correct password back to the web server when it can do the check at the database?


I would as well go for a stored proc, it's definitely more secure because you don't have to send the correct password anywhere.

The way this code handles it, by sending all users and their password to the client is just about the worst security you can have...

captcha: waffles. Oh great, now I feel like eating some...


What the hell is wrong with (in a imaginary syntax):

hashedPass = escape(md5_or_whatever_hash_function(theRawPassword));
user = escape(userEntered);
sql = "select * from users where user = $user and hashedPass = $hashedPass";
executeSQL(sql)

It doesn't send unencrypted passwords over the wire, is immune to injection. You just have to count how many rows returned and you're done.

Re: But It Worked in the Demo

2007-01-26 10:54 • by jpa (unregistered)
I'm surprised that no-one has yet to mention the insecurity of having a testuser stored in the database, and probably also the password for it in the unit testing code.

Re: But It Worked in the Demo

2007-01-26 10:54 • by AT (unregistered)
113738 in reply to 113730
Fredric:
J:
AT:
J:
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.


Do you think that makes the system more secure? You do realize that the hashed password already must go from the user's computer to the Web server, then from the Web server to the database right?


Do you think it makes the system less secure? What if the user enters the wrong password? What if the username isn't even valid? Why send the correct password back to the web server when it can do the check at the database?


I would as well go for a stored proc, it's definitely more secure because you don't have to send the correct password anywhere.

The way this code handles it, by sending all users and their password to the client is just about the worst security you can have...

captcha: waffles. Oh great, now I feel like eating some...


First, the web server and the client are not the same thing. Second, authenticating with a stored proc provides a security "advantage" only in the miniscule number of cases where someone is sniffing the network and also attempting failed logins with known usernames. Of course, they can still capture the hashed passwords of all the other users accessing the system at the same time as those passwords are sent to the Web and database servers.

Re: But It Worked in the Demo

2007-01-26 10:57 • by fmobus
113739 in reply to 113737
jpa:
I'm surprised that no-one has yet to mention the insecurity of having a testuser stored in the database, and probably also the password for it in the unit testing code.


Well, usually one would setup a "mockup" database on the test environment and use a "hot" database for production... For a clearer explanation on this, see Rails.

Re: But It Worked in the Demo

2007-01-26 10:58 • by Killen (unregistered)
113740 in reply to 113698
Aaron:
The Real WTF™®? is that he didn't use a salt.


Actually, there's no proof that he didn't use a salt in this example.

Captcha: muhahaha

Re: But It Worked in the Demo

2007-01-26 10:58 • by AT (unregistered)
113741 in reply to 113736
fmobus:
Fredric:
J:
AT:
J:
Why add a WHERE clause at all? There is no good reason to send the password back to the web server, hashed or not. A stored proc that checks the login and returns a true / false would eliminate the issue entirely.


Do you think that makes the system more secure? You do realize that the hashed password already must go from the user's computer to the Web server, then from the Web server to the database right?


Do you think it makes the system less secure? What if the user enters the wrong password? What if the username isn't even valid? Why send the correct password back to the web server when it can do the check at the database?


I would as well go for a stored proc, it's definitely more secure because you don't have to send the correct password anywhere.

The way this code handles it, by sending all users and their password to the client is just about the worst security you can have...

captcha: waffles. Oh great, now I feel like eating some...


What the hell is wrong with (in a imaginary syntax):

hashedPass = escape(md5_or_whatever_hash_function(theRawPassword));
user = escape(userEntered);
sql = "select * from users where user = $user and hashedPass = $hashedPass";
executeSQL(sql)

It doesn't send unencrypted passwords over the wire, is immune to injection. You just have to count how many rows returned and you're done.


How does the hashed password in your SQL query get to the database server? On a floppy disk? This method also doesn't allow you to tell the user whether their username or password is invalid.

Re: But It Worked in the Demo

2007-01-26 11:02 • by chooks
113744 in reply to 113732
While being entirely unable to login represents some inconvenience for the typical user, this implementation is preferred because of the superior security. A hacker can’t just guess anyone’s password. It has to be the password of the last user in the table. You can’t have security without some cost to usability.


Exactly. It's a feature. Not a bug.

Re: But It Worked in the Demo

2007-01-26 11:06 • by Simon (unregistered)
113747 in reply to 113741
Why would you want to tell your users that? It's generally accepted that telling the user that the username was okay while the password is not is a bad security practice, because then you've just confirmed to the attacker that now they only need to guess a password, and not a username/password combination.

Re: But It Worked in the Demo

2007-01-26 11:07 • by fmobus
113748 in reply to 113741
AT:
fmobus:


What the hell is wrong with (in a imaginary syntax):

hashedPass = escape(md5_or_whatever_hash_function(theRawPassword));
user = escape(userEntered);
sql = "select * from users where user = $user and hashedPass = $hashedPass";
executeSQL(sql)

It doesn't send unencrypted passwords over the wire, is immune to injection. You just have to count how many rows returned and you're done.


How does the hashed password in your SQL query get to the database server? On a floppy disk? This method also doesn't allow you to tell the user whether their username or password is invalid.


The $hashedPass variable interpolated and properly escaped in the query, maybe?

Regarding not being able to tell whether the name or the password is wrong, I think this is actually a good thing.

Re: But It Worked in the Demo

2007-01-26 11:11 • by Pap
113749 in reply to 113741
AT:
How does the hashed password in your SQL query get to the database server? On a floppy disk? This method also doesn't allow you to tell the user whether their username or password is invalid.


Or tell the client that their password was correct but not their username.

;]

Re: But It Worked in the Demo

2007-01-26 11:15 • by fmobus
Furthermore, one could easily add a "salt" mechanism to avoid birthday attacks. For instance (again, imaginary syntax):


user = escape(user);
salt = executeSql("select salt from users where user = $user");
hashedPass = escape(hash_function_with_salt(rawPass, salt));
userRecord = executeSql("select * from users where user = $user and hashedPass = $pass");

(or something like this).
« PrevPage 1 | Page 2 | Page 3 | Page 4 | Page 5Next »

Add Comment