Do all the things like ++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatarSign Up
Get a devDuck
Rubber duck debugging has never been so cute! Get your favorite coding language devDuckBuy Now
Search - "no hashing"
1. Forgot my password.
2. Clicked "Forgot" password button.
3. Received my forgotten password as plain text in my email7
I was reviewing one dev's work. It was in PHP. He used MD5 for password hashing. I told him to use to password_hash function as MD5 is not secure...
He said no we can't get a password from MD5 hashed string. It's one way hashing...
So I asked him to take couple of passwords from the users table and try to decode those in any online MD5 decoder and call me after that if he still thinks MD5 is secure.
I have not got any call from him since.18
So, some time ago, I was working for a complete puckered anus of a cosmetics company on their ecommerce product. Won't name names, but they're shitty and known for MLM. If you're clever, go you ;)
Anyways, over the course of years they brought in a competent firm to implement their service layer. I'd even worked with them in the past and it was designed to handle a frankly ridiculous-scale load. After they got the 1.0 released, the manager was replaced with some absolutely talentless, chauvinist cuntrag from a phone company that is well known for having 99% indian devs and not being able to heard now. He of course brought in his number two, worked on making life miserable and running everyone on the team off; inside of a year the entire team was ex-said-phone-company.
Watching the decay of this product was a sheer joy. They cratered the database numerous times during peak-load periods, caused $20M in redis-cluster cost overrun, ended up submitting hundreds of erroneous and duplicate orders, and mailed almost $40K worth of product to a random guy in outer mongolia who is , we can only hope, now enjoying his new life as an instagram influencer. They even terminally broke the automatic metadata, and hired THIRTY PEOPLE to sit there and do nothing but edit swagger. And it was still both wrong and unusable.
Over the course of two years, I ended up rewriting large portions of their infra surrounding the centralized service cancer to do things like, "implement security," as well as cut memory usage and runtimes down by quite literally 100x in the worst cases.
It was during this time I discovered a rather critical flaw. This is the story of what, how and how can you fucking even be that stupid. The issue relates to users and their reports and their ability to order.
I first found this issue looking at some erroneous data for a low value order and went, "There's no fucking way, they're fucking stupid, but this is borderline criminal." It was easy to miss, but someone in a top down reporting chain had submitted an order for someone else in a different org. Shouldn't be possible, but here was that order staring me in the face.
So I set to work seeing if we'd pwned ourselves as an org. I spend a few hours poring over logs from the log service and dynatrace trying to recreate what happened. I first tested to see if I could get a user, not something that was usually done because auth identity was pervasive. I discover the users are INCREMENTAL int values they used for ids in the database when requesting from the API, so naturally I have a full list of users and their title and relative position, as well as reports and descendants in about 10 minutes.
I try the happy path of setting values for random, known payment methods and org structures similar to the impossible order, and submitting as a normal user, no dice. Several more tries and I'm confident this isn't the vector.
Exhausting that option, I look at the protocol for a type of order in the system that allowed higher level people to impersonate people below them and use their own payment info for descendant report orders. I see that all of the data for this transaction is stored in a cookie. Few tests later, I discover the UI has no forgery checks, hashing, etc, and just fucking trusts whatever is present in that cookie.
An hour of tweaking later, I'm impersonating a director as a bottom rung employee. Score. So I fill a cart with a bunch of test items and proceed to checkout. There, in all its glory are the director's payment options. I select one and am presented with:
"please reenter card number to validate."
Bupkiss. Dead end.
OR SO YOU WOULD THINK.
One unimportant detail I noticed during my log investigations that the shit slinging GUI monkeys who butchered the system didn't was, on a failed attempt to submit payment in the DB, the logs were filled with messages like:
"Failed to submit order for [userid] with credit card id [id], number [FULL CREDIT CARD NUMBER]"
One submit click later and the user's credit card number drops into lnav like a gatcha prize. I dutifully rerun the checkout and got an email send notification in the logs for successful transfer to fulfillment. Order placed. Some continued experimentation later and the truth is evident:
With an authenticated user or any privilege, you could place any order, as anyone, using anyon's payment methods and have it sent anywhere.
So naturally, I pack the crucifixion-worthy body of evidence up and walk it into the IT director's office. I show him the defect, and he turns sheet fucking white. He knows there's no recovering from it, and there's no way his shitstick service team can handle fixing it. Somewhere in his tiny little grinchly manager's heart he knew they'd caused it, and he was to blame for being a shit captain to the SS Failboat. He replies quietly, "You will never speak of this to anyone, fix this discretely." Straight up hitler's bunker meme rage.14
when you work for a place that has plain text passwords in the db. lol
I asked head of department if he knew what salting/hashing passwords was and he said no.... is this real life?19
Story: Password hashing and UTF-8
Context: PHP 5.6, 270kloc 15+ years legacy project. ~3 years ago. tl;dr at bottom.
Password hashing & verification was done with an obsolete way of hashing passwords. I was given the task to update our password handler to from now on generate passwords with PHP's good built-in password hashing function.
It was decided that old passwords still needed to work, instead of prompting users to set a new password. The old password verification still had to function in conjunction with the new.
The previous password handler was split into multiple classes, due to (I assume) poor structuring and shoehorning in an object oriented approach. Furthermore, it abused global variables.
A new password handler had to be created.
I implemented the new password verification and creation methods (which now used PHP internal password functions), and it worked perfectly. Then to get the old password verification to work.
I removed all obsolete methods from the old handler, and was left with a hashing function which took in a password, salt, and a secret key. I copied this code into the new handler.
It failed. It returned "Password does not match" for old passwords. I was unsure what had happened here. I did all sorts of shotgun debugging. I ended up with two versions of the login page next to each other, which used the old and new code respectively. I started modifying the original code, extracting variables, logging, you name it. I ended up with exactly the same snippets of code in both password handlers, and yet it failed.
The culprit? The character encoding.
Because this project was over a decade old, the .php-file had the encoding 'windows-1252'. When I created the new password handler, my IDE set the file encoding to 'UTF-8'. Then when I copied the secret, my IDE converted the string to 'UTF-8', effectively changing the value of the secret and causing any password verifications to fail. The solution was to manually create a string using the byte values in the old secret.
It is these extreme, obscene, scenarios which makes working with legacy projects a living hell. In this scenario, it was my IDE at fault for changing the character encoding.
But my IDE is not the root problem. No, I blame it on the lack of maintenance from previous developers. Not keeping the codebase up to standard causes problems like this in the long run.
tl;dr: copied hash secret to a file with another encoding. IDE changed the byte values for those characters, causing password verification to fail. fml.2
Installed my telecom service provider's app for checking new packs. Didn't remember the password. Hit forgot password! I get my password in plain text in sms!
Fuck, it's one of the leading service provider in the country!
Till now i had only read about it, but never encountered it! Any ideas as to how to approach them?2
It's gotten to the point where I am legitimately impressed when I can tell a service is hashing their passwords.
All of these unnecessary complications of "must not have more than 2 of the same character in a row" but "can't be more than 12 characters" requirements make me think that the passwords are being saved in plain text.
Amazon and Dropbox do it right - present the user with an input box and no requirements printed anywhere.8
Major rant incoming. Before I start ranting I’ll say that I totally respect my professor’s past. He worked on some really impressive major developments for the military and other companies a long time ago. Was made an engineering fellow at Raytheon for some GPS software he developed (or lead a team on I should say) and ended up dropping fellowship because of his health. But I’m FUCKING sick of it. So fucking fed up with my professor. This class is “Data Structures in C++” and keep in mind that I’ve been programming in C++ for almost 10 years with it being my primary and first language in OOP.
Throughout this entire class, the teacher has been making huge mistakes by saying things that aren’t right or just simply not knowing how to teach such as telling the students that “int& varOne = varTwo” was an address getting put into a variable until I corrected him about it being a reference and he proceeded to skip all reference slides or steps through sorting algorithms that are wrong or he doesn’t remember how to do it and saying, “So then it gets to this part and....it uh....does that and gets this value and so that’s how you do it *doesnt do rest of it and skips slide*”.
First presentation I did on doubly linked lists. I decided to go above and beyond and write my own code that had a menu to add, insert at position n, delete, print, etc for a doubly linked list. When I go to pull out my code he tells me that I didn’t say anything about a doubly linked list’s tail and head nodes each have a pointer pointing to null and so I was getting docked points. I told him I did actually say it and another classmate spoke up and said “Ya” and he cuts off saying, “No you didn’t”. To which I started to say I’ll show you my slides but he cut me off mid sentence and just yelled, “Nope!”. He docked me 20% and gave me a B- because of that. I had 1 slide where I had a bullet point mentioning it and 2 slides with visual models showing that the head node’s previousNode* and the tail node’s nextNode* pointed to null.
Another classmate that’s never coded in his life had screenshots of code from online (literally all his slides were a screenshot of the next part of code until it finished implementing a binary search tree) and literally read the code line by line, “class node, node pointer node, ......for int i equals zero, i is less than tree dot length er length of tree that is, um i plus plus.....”
Professor yelled at him like 4 times about reading directly from slide and not saying what the code does and he would reply with, “Yes sir” and then continue to read again because there was nothing else he could do.
Ya, he got the same grade as me.
Today I had my second and final presentation. I did it on “Separate Chaining”, a hashing collision resolution. This time I said fuck writing my own code, he didn’t give two shits last time when everyone else just screenshot online example code but me so I decided I’d focus on the PowerPoint and amp it up with animations on models I made with the shapes in PowerPoint. Get 2 slides in and he goes,
Prof: Stop! Go back one slide.
Me: Uh alright, *click*
(Slide showing the 3 collision resolutions: Open Addressing, Separate Chaining, and Re-Hashing)
Prof: Aren’t you forgetting something?
Me: ....Not that I know of sir
Prof: I see Open addressing, also called Open Hashing, but where’s Closed Hashing?
Me: I believe that’s what Seperate Chaining is sir
Me: I’m pretty sure it is
*Class nods and agrees*
Prof: Oh never mind, I didn’t see it right
Get another 4 slides in before:
Prof: Stop! Go back one slide
Me: .......alright *click*
(Professor loses train of thought? Doesn’t mention anything about this slide)
Prof: I er....um, I don’t understand why you decided not to mention the other, er, other types of Chaining. I thought you were going to back on that slide with all the squares (model of hash table with animations moving things around to visualize inserting a value with a collision that I spent hours on) but you didn’t.
(I haven’t finished the second half of my presentation yet you fuck! What if I had it there?)
Me: I never saw anything on any other types of Chaining professor
Prof: I’m pretty sure there’s one that I think combines Open Addressing and Separate Chaining
Me: That doesn’t make sense sir. *explanation why* I did a lot of research and I never saw any other.
Prof: There are, you should have included them.
(I check after I finish. Google comes up with no other Chaining collision resolution)
He docks me 20% and gives me a B- AGAIN! Both presentation grades have feedback saying, “MrCush, I won’t go into the issues we discussed but overall not bad”.
Thanks for being so specific on a whole 20% deduction prick! Oh wait, is it because you don’t have specifics?
Bye 3.8 GPA
Is it me or does he have something against me?7
- Implemented oauth1 - no body hashing
- URL contains credentials in plain text
- Used Azure API management feature as a proxy of the our API, however the documentation was on the our API, thus exposing the API URL with no management to developers.
- easy resource DDoSing because each trial user got a DB, the registration process did not have bot checks. You could literally freeze the db instance by spamming registration requests.
Made a simple jwt auth server with express (node.js) . Used one JWT library that took me no longer than 5 minutes to understand almost all of its functionality and therefore quickly get to work.
Started the JWT auth flow for another app in .NET core 2.0. Microsoft has a recommended JWT library with more than 20 million downloads. Sooooo complex. Every tutorial found is a 50 minute minimum read with an outrageous amount of understanding around the library to even get a JWT token generated.
I guess thats part of the reason I've gone into c# was so i could become much more of a seasoned developer that has a more low level perspective but this is ridiculous.
with the npm library its literally a generateToken method that takes your encryption type string, an object of your claims and your secret to use for signing. With the nuget library im having to do the HMAC hashing manually, utilize more then 10 classes and peace them all together.11