• highphilosopher (unregistered)

    I've always loved the superuser password '%'

    FIRST

  • (cs) in reply to highphilosopher

    %? You must be confusing = with LIKE.

    I'm having trouble seeing the WTF here. Is it that there's no apparent use of the username? Or is it that the password is being sent in the clear between the database server and the VB client?

  • Roadhead (unregistered)

    "Logging into the system is a bug, How did you do it?"

  • Oxin (unregistered) in reply to Maurits
    Maurits:
    %? You must be confusing = with LIKE.

    I'm having trouble seeing the WTF here. Is it that there's no apparent use of the username? Or is it that the password is being sent in the clear between the database server and the VB client?

    I'm not sure what the WTF is either. Sure it's bad code but it looks like it works. It might be vulnerable to sql injection depending on how much Utils.ConvertToDBString(txtPassword.Text) sanitizes input but if _Password is set before the button press somewhere, the sql injection code is unreachable.

  • Dr.Dre (unregistered) in reply to Maurits
    Maurits:
    I'm having trouble seeing the WTF here. Is it that there's no apparent use of the username? Or is it that the password is being sent in the clear between the database server and the VB client?

    I guess it's that there will always be a dataset returned (containing a table with probably no contents), so you'll always get an OK.

  • John (unregistered)

    I'm not a VB expert, but it looks as if any password stored in the passwords table will work to log in. If there are two users, Tom and Jerry, Tom can use his password to log in to Jerry's account. The check is just making sure the entered password exists in the DB, not that it is the correct password for the user. Kinda makes encryption useless.

    Maybe its not a bug. Maybe its a feature

  • Vollhorst (unregistered)

    The problem is that the function does not check if the passwords begins with a Q or Z.

  • Occasional Reader (unregistered)

    I'm struggling to see a major WTF here - there are a few minor ones - such as testing a variable which you assume should have been populated in there somewhere (_Password), assuming that there is only 1 record in the password table (or worse are you just checking that the user has selected one of the passwords in that table), storing passwords in plain text but to be honest they're not completely evil. Plain text passwords are fine for certain non-critical applications.

    Is there something more nefarious that I've completely missed here?

  • Michael (unregistered) in reply to John
    John:
    I'm not a VB expert, but it looks as if any password stored in the passwords table will work to log in. If there are two users, Tom and Jerry, Tom can use his password to log in to Jerry's account. The check is just making sure the entered password exists in the DB, not that it is the correct password for the user. Kinda makes encryption useless.

    Maybe its not a bug. Maybe its a feature

  • Patrick (unregistered)

    My brother once tried to break the accepted norm and create a login system without usernames. You log in with your password, that should be enough. After half an hour attempting to explain to him that usernames are good, it eventually boiled down to this: "You cannot create an account with this password because another account is already using it." "Oh. But they don't know what user id that password is for!" "The what? The username?" "Oh."

  • Michael (unregistered) in reply to Michael
    John:
    I'm not a VB expert, but it looks as if any password stored in the passwords table will work to log in. If there are two users, Tom and Jerry, Tom can use his password to log in to Jerry's account. The check is just making sure the entered password exists in the DB, not that it is the correct password for the user. Kinda makes encryption useless.

    Maybe its not a bug. Maybe its a feature

    And especially that the password is probably stored in plain text in the DB. Or he requires each user to enter his password already either as ROT13 or MD5 or AES encrypted. Amazing.

  • GrammarNazi (unregistered) in reply to Vollhorst
    Vollhorst:
    The problem is that the function does not check if the passwords begins with a Q or Z.
    winner winner, chicken dinner
  • Nick J (unregistered)

    I'm no VB expert, but these are my thoughts/assumptions:

    Utils.ConvertToDBString cleans the input to prevent SQL Injection

    _password may contain a programmer back-door password, so if it's present in the code, it won't even use the database at all and it's only possible to use that one password.

    There's no checking of usernames at all.

    Microsoft dialect of SQL is so ugly, all those []'s all over the place. Horrible.

  • Joe (unregistered) in reply to John

    For what it's worth, the Citadel-86 BBS software back in the 80s and early 90s had usernames (obviously), passwords (obviously), but you only logged in with a password (not-so-obviously). While there was functionality to lockout a session after X failed login attempts, it was still prone to brute-forcing...

    ...or the inevitable creation of your account, only to be told "this password is already in use". It is? Hot damn!

  • mr_smith (unregistered) in reply to Patrick
    Patrick:
    My brother once tried to break the accepted norm and create a login system without usernames. You log in with your password, that should be enough. After half an hour attempting to explain to him that usernames are good, it eventually boiled down to this: "You cannot create an account with this password because another account is already using it." "Oh. But they don't know what user id that password is for!" "The what? The username?" "Oh."

    I once had a boss who had this plan. He eventually gave up on it though - I'm not sure why. He also felt that multivalue relational databases were better than normalized because you could have one to many relationships in multivalue. Great place to work!

  • Patrick (unregistered) in reply to Occasional Reader
    Occasional Reader:
    I'm struggling to see a major WTF here - there are a few minor ones - such as testing a variable which you assume should have been populated in there somewhere (_Password), assuming that there is only 1 record in the password table (or worse are you just checking that the user has selected one of the passwords in that table), storing passwords in plain text but to be honest they're not completely evil. Plain text passwords are fine for certain non-critical applications.

    Is there something more nefarious that I've completely missed here?

    It's all of them put together.

    • The password is not encrypted, even though there is a simple ROT13 and perfectly good AES encryption system just a function call away.
    • The username is not implemented at all, meaning that any username will log in as long as a password matches.
    • Any password. As long as it's in there.
    • If two people have the same password, someone will log in to the wrong account and be unable to access their own.
    • The condition is that the dataset has been assigned a value, even though "zero rows" and "two rows" and so on are still valid, resulting in a successful login every time.
    • Even if the login could be unsuccessful, the password may still be accepted by comparing it to a variable that gets set somewhere unseen.

    captcha: gravis. this is a gravisituation forsecurity.

  • Robert B (unregistered) in reply to Patrick

    Way back in the age of mini-computers the IRIS, OS for Data general Nova machines, had this feature. Security audits showed it to be significantly more secure than traditional username - password combinations.

    Of course, I still didn't like it :)

  • Robert B (unregistered) in reply to Patrick

    Way back in the age of mini-computers the IRIS, OS for Data general Nova machines, had this feature. Security audits showed it to be significantly more secure than traditional username - password combinations.

    Of course, I still didn't like it :)

  • eric76 (unregistered) in reply to Patrick
    Patrick:
    My brother once tried to break the accepted norm and create a login system without usernames. You log in with your password, that should be enough. After half an hour attempting to explain to him that usernames are good, it eventually boiled down to this: "You cannot create an account with this password because another account is already using it." "Oh. But they don't know what user id that password is for!" "The what? The username?" "Oh."
    I knew someone who modified the system on an old PDP-11 running RSTS/E to ignore the passwords. Instead, it associated each account with a record in the payroll file and when you were logging on, it would pull your record from the payroll file and ask you a random question about the record.

    Sometimes the question was pretty easy such as asking for the address. Sometimes the question was not so easy such as asking for what your year to date withholding is through the last payroll period.

    The result was that you pretty much needed a current copy of your records from the payroll file to be able to log onto the computer.

    It didn't take too long to revert to the canonical password approach.

  • Anonymous (unregistered)

    This is a usability feature. If anyone forgets their password they'll still be able to log in to the system with "password" because we all know that at least one idiot user will have chosen that as their actual pass ("root", "admin", "god" and "love" are also acceptable substitutes). This is actually a very clever recovery technique.

  • (cs)

    I like how, if the backdoor (_Password) is set to anything at all, you can ONLY login via that backdoor . . . it is impossible to login normally.

  • Daniel Pope (unregistered)

    Storing passwords unencrypted is not a WTF.

  • Anonymous (unregistered) in reply to Daniel Pope
    Daniel Pope:
    Storing passwords unencrypted is not a WTF.
    Can I get a "whooooooosh" for this man?
  • justsomedude (unregistered)

    My problem is the article claims this codemonkey is an excllent VB developer, but is terrible at VB.NET. However, the example provided is an errorin the the thought process itself, not a problem getting .NET to do what is desired.

    For me TRWTF is saying he was an excllent VB6 dev.

  • The_Assimilator (unregistered) in reply to Anonymous

    On this site, seeing unencrypted password storage code is definitely not a WTF.

  • Shredder (unregistered)

    bool Is_It_a_WTF_or_isnt_it(string _inpArticle) { bool isawtf; if (isawtf!=false) isawtf=false; for (int i=0; i<8; i++) { switch (i) { case 0: if (_inpArticle == "wtf") isawtf=true; break; case 1: if (_inpArticle == "Wtf") isawtf=true; break; case 2: if (_inpArticle == "wTf") isawtf=true; break; case 3: if (_inpArticle == "wtF") isawtf=true; break; case 4: if (_inpArticle == "WTf") isawtf=true; break; case 5: if (_inpArticle == "WtF") isawtf=true; break; case 6: if (_inpArticle == "wTF") isawtf=true; break; case 7: if (_inpArticle == "WTF") isawtf=true; break; } } if (!isawtf != false) return false; if (isawtf != false) return true; return "brillant"; }

    I'm not a vb person. I'm having trouble understanding.

  • (cs)

    whooooooosh!

    I'll go tell that to my boss right now, I'm have this feeling about getting a raise.

  • Crono (unregistered) in reply to Patrick
    The condition is that the dataset has been assigned a value, even though "zero rows" and "two rows" and so on are still valid, resulting in a successful login every time.

    True, unless MDI.GetDataSet implementation is coded in a way that if there's no records, it returns Nothing.

    Of course that would be bad coding too! :)

  • Crono (unregistered) in reply to Anonymous
    Anonymous:
    Daniel Pope:
    Storing passwords unencrypted is not a WTF.
    Can I get a "whooooooosh" for this man?

    Actually I kinda agree it's not a worthy WTF! :D

    Still bad, though! ;)

  • Jadawin (unregistered) in reply to justsomedude

    For me TRWTF is saying there is an excellent VB6 dev.

    Fixed your typo for you. :)

  • PJ Volk (unregistered) in reply to Daniel Pope
    Daniel Pope:
    Storing passwords unencrypted is not a WTF.

    What's the worst that could happen...

    DoD testing, they sniff the network, and grep the system. If they find their password, you get a critical finding. Fix it, or take your box and go home.

    MD5 is easy, but won't make you as famous. "Password information for 1.2 million users stolen from PopeBank" Now THAT will make you famous!

  • qurious (unregistered)

    so who messed this up? the original 3rd party developer, or the in house developer converting to vb.net?

  • Daniel Pope (unregistered) in reply to PJ Volk
    PJ Volk:
    Daniel Pope:
    Storing passwords unencrypted is not a WTF.
    What's the worst that could happen...

    DoD testing, they sniff the network, and grep the system. If they find their password, you get a critical finding. Fix it, or take your box and go home.

    If you invent situations where it would be a ludicrous thing to do, then, tautologically, it's a ludicrous thing to do.
    MD5 is easy, but won't make you as famous. "Password information for 1.2 million users stolen from PopeBank" Now THAT will make you famous!
    Challenge-response authentication requires unencrypted passwords. System security is often more important than password security.

    For example, my bank stores my password unencrypted. It does this so it can challenge me for individual characters from it rather than asking me to enter the whole password.

  • Anonymous (unregistered) in reply to Daniel Pope
    Daniel Pope:
    Challenge-response authentication requires unencrypted passwords. System security is often more important than password security.

    For example, my bank stores my password unencrypted. It does this so it can challenge me for individual characters from it rather than asking me to enter the whole password.

    I would strongly recommmend you bank somewhere else. If a bank wants to implement this kind of security they should do it with an additional piece of information, not your password. Lots of banks do this, but only the clueless ones do it with your actual password.

  • (cs)
    Mark Bowytz:
    Anti-patterns and WTFs-a-plenty, it was hard to pick out just one example, but the following jumped out.

    Protip: using two metaphors that have nearly opposite meanings to describe the same thing can often render a sentence meaningless.

  • JarFil (unregistered) in reply to Daniel Pope
    Daniel Pope:
    For example, my bank stores my password unencrypted. It does this so it can challenge me for individual characters from it rather than asking me to enter the whole password.

    They could keep salted MD5 hashes of the right answer for every possible challenge. That would be, how many? 65, 87 or something like that? I say it's not a big deal.

    In a well planned authentication chain, there is no way in which keeping cleartext passwords would increase security.

  • (cs) in reply to Daniel Pope
    Daniel Pope:
    Challenge-response authentication requires unencrypted passwords. System security is often more important than password security.

    For example, my bank stores my password unencrypted. It does this so it can challenge me for individual characters from it rather than asking me to enter the whole password.

    Please tell me you are joking. My irony detection module is currently in the shop being serviced...

  • KRex (unregistered) in reply to Daniel Pope
    Daniel Pope:
    PJ Volk:
    Daniel Pope:
    Storing passwords unencrypted is not a WTF.
    What's the worst that could happen...

    DoD testing, they sniff the network, and grep the system. If they find their password, you get a critical finding. Fix it, or take your box and go home.

    If you invent situations where it would be a ludicrous thing to do, then, tautologically, it's a ludicrous thing to do.
    MD5 is easy, but won't make you as famous. "Password information for 1.2 million users stolen from PopeBank" Now THAT will make you famous!
    Challenge-response authentication requires unencrypted passwords. System security is often more important than password security.

    For example, my bank stores my password unencrypted. It does this so it can challenge me for individual characters from it rather than asking me to enter the whole password.

    Users password is in the db. If you can get into the db to get the users password, you don't need to know the users password.

  • (cs) in reply to KRex
    KRex:
    Users password is in the db. If you can get into the db to get the users password, you don't need to know the users password.

    If the user got to pick their password, it's likely the same password they use for other things.

    If you don't have their password, you don't have to worry about someone stealing it from you, limiting your liability.

  • (cs)

    Hmmm... maybe the database connection is set to NT Trusted Authentication, and [dbo].[Password] is:

    CREATE VIEW [Password] AS SELECT * FROM [Users] WHERE [Users].[Username] = USER_NAME()

    This begs the question - if the user is already authenticated, why ask them for a password?

    Maybe this is the password change screen.

  • Herohtar (unregistered) in reply to Someone You Know
    Someone You Know:
    Mark Bowytz:
    Anti-patterns and WTFs-a-plenty, it was hard to pick out just one example, but the following jumped out.

    Protip: using two metaphors that have nearly opposite meanings to describe the same thing can often render a sentence meaningless.

    Protip: neither of those are metaphors. The second is a personification, the first is just a plain old statement.

  • Jaco (unregistered)

    I'm a VB.NET dev (and I think reasonably good at it), but this is the work of someone less than amateur.

    Funny how the author of this little example managed to put so many WTFs in what should be a rather simple method.

    (Captcha: facilisi - what the author escaped from?)

  • (cs)

    Oracle allows for encrypting a column at the database level, allowing the application to only use clear text while only storing encrypted text. In some ways this method can provide better security. From the original post, we don't know that the passwords are not encrypted in the database.

    Of course encrypted columns cannot be indexed and searching a non indexed column provides its own WTF.

  • SR (unregistered) in reply to Grimoire
    Grimoire:
    Please tell me you are joking. My irony detection module is currently in the shop being serviced...

    Whether the OP was joking or not, try this for a password security WTF.

  • abico (unregistered) in reply to Someone You Know
    Someone You Know:
    Mark Bowytz:
    Anti-patterns and WTFs-a-plenty, it was hard to pick out just one example, but the following jumped out.

    Protip: using two metaphors that have nearly opposite meanings to describe the same thing can often render a sentence meaningless.

    Thanks for that, that bowytzed sentence was driving me nuts, too.

    ARRRGGH, matey.

  • BeKaY (unregistered)
    If String.IsNullOrEmpty(_Password) Then
        do stuff
    

    Judging by the name of the function IsNullOrEmpty, it should return true if the password is either Null or Empty, that means that it will only check the password in the database if the password field is left blank.

  • Richard (unregistered)

    Assuming that everyone agrees that WTF-worthy or not, there is a better solution to the code problem presented, can we move on to the part where ROT13 was discussed as a valid way of doing anything?

    CAPTCHA: Validus. This is what ROT13 is not, though if you believe ROT13 is, I suggest you do it twice in a row to double the security you get.

  • Jay (unregistered)

    This example might have been more interesting or amusing with a little more explanation.

    I don't know VB.Net, but from what I can figure out here, the function is referencing two different password fields: txtPassword.text, which I presume is coming from the input screen, and _password, which comes from ... where? It must be a class or global variable, but how is it populated? If _password is not null, then it compares the entered password against this value. Otherwise it looks up the entered password on the database.

    There does seem to be a problem here, as others have noted, that the user id is not used as part of the lookup, so apparently you can log in to any user id with any password, i.e. your password will get you in to your boss's account. Or better still, into the account of someone who has privileges to update salaries.

    But where does _password come from? The code snippet does not reveal this.

  • VB Master, VB Pasta (unregistered) in reply to Jay
    Jay:
    This example might have been more interesting or amusing with a little more explanation.

    I don't know VB.Net, but from what I can figure out here, the function is referencing two different password fields: txtPassword.text, which I presume is coming from the input screen, and _password, which comes from ... where? It must be a class or global variable, but how is it populated? If _password is not null, then it compares the entered password against this value. Otherwise it looks up the entered password on the database.

    There does seem to be a problem here, as others have noted, that the user id is not used as part of the lookup, so apparently you can log in to any user id with any password, i.e. your password will get you in to your boss's account. Or better still, into the account of someone who has privileges to update salaries.

    But where does _password come from? The code snippet does not reveal this.

    .net standards - "_" prefix is for class variables. i imagine something like this:

    Class SomeCrap Inherits Form

    Dim _Password As String

    Public Sub New() ...snip... #if DEBUG _Password = "DebugModePassword" #endif End Sub

    ... snip ...

    End Class

    result is the variable is only set when the app is compiled in debug mode. not that this would make it any better, obviously.

  • Jay (unregistered) in reply to Maurits
    Maurits:
    KRex:
    Users password is in the db. If you can get into the db to get the users password, you don't need to know the users password.

    Yes, a point I have occasionally pondered myself. I suppose it's possible that you could read the password table but not some other table that that user can get to, but this seems to be straining the issue. If you can update the DB, the whole issue quickly becomes moot: You can set any password you like, get in and do your damage, and then put it back.

    Maurits:
    If the user got to pick their password, it's likely the same password they use for other things.

    Okay, true. I suppose I could take the user's password on our system and try to access his bank account or some such with the same password.

    Maurits:
    If you don't have their password, you don't have to worry about someone stealing it from you, limiting your liability.

    But if we're the owners of the system in question, then this brings us back to the original post: Anyone who can access the database to steal the password can access the database, and therefore they're already in. I'm not a lawyer, but suppose you tried this defense: "But judge, we shouldn't be liable here! We were very scrupulous about keeping all the door keys safe! We're absolutely positive that not one key fell into unauthorized hands. We just forgot to lock the door and the thieves just walked in. That's not our fault. We kept the keys absolutely safe." I'm guessing that wouldn't take you very far.

    Unless you're thinking in terms of your previous point about the user using the same password on other accounts. There may be something there.

Leave a comment on “Encryption Misinformation”

Log In or post as a guest

Replying to comment #:

« Return to Article