This is frighteningly standard across most companies with no serious planning phase for new features, and no code review process. Fact is, some developer was told to create a REST API for password resets, and to return the secret token so that the (internal to the company!) client can send the email containing that token. This developer did their job correctly.
At some point, a different developer was told to consume this endpoint, send the related email, and tell the end user (browser client) that the email was sent. This second developer is not part of the "senior services team" who designed the above API, which is perfectly valid. Instead, this is a junior developer taking on their first task at the company. "Take this password reset API endpoint, and integrate it". In addition to queuing the password reset email with the token embedded within it, they also accidentally proxy the password reset service's payload to the browser. No intermediate or senior develop reviewed this new employee's PR; if they did bother to look at it, they only checked for coding standard violations (eg. indentation), without taking the effort to understand the logic of the code.
This is actually extremely common, unfortunately. The server-side layer that directly interacts with clients (ie. browsers) is generally delegated to the most junior developers, because it's menial and uninteresting work to connect the backend services to the browser. The current senior developers spent years working on that kind of garbage already, and they'd rather work on the "more interesting/advanced" backend work. Thus, the junior developers whose skills aren't yet honed are stuck–typically unsupervised–working on the front-facing components.
Also, this routinely happens at companies which rush every feature out the door with modern "agile" practices. The sprint is almost over! Quick, deliver all features by tomorrow to keep up our velocity and avoid a sprint review with negative feedback! Just merge it and push to prod without QA on a Friday at 4pm!
If only the above was a comedy routine, rather than what it truly is: the genuine reality at a large number of companies.
Agreed, this is far too basic for the "oh yeah, a junior developer might not have noticed it" excuse.
Hacker News seems to assume juniors are useless, from the comments I've seen to date - but they should be able to _think_ and solve problems, even if they're less experienced at interacting with stakeholders, designing system architecture etc.
If I had to guess, the developer used that to debug the reset token to QA if the flow worked; then it was forgotten and skipped past Code Review since the team just left a LGTM without actually looking at the code OR there were to many changes to the PR.
I mean, I don't think it's that hard to surmise how something like this could have happened. Yes, the bug is egregiously bad, but I don't think it's likely the developer purposely designed it to work like that. Some simple possibilities: (a) perhaps the page was originally intended only to be accessible from a user hitting from a private link sent to their email address (i.e. how normal password resets work, or (b) The API in use was designed to only be accessed server-side, but it was inadvertently proxied through to a client-side call.
Again, yes, the bug is very bad. Software is complex, and humans are humans, and it's not difficult to imagine how these bugs occur.
I don't think the developer designed it to work that way either, but something like this only happens when the person creating it, or the people touching it after either don't know how important this interaction flow is or don't take it seriously enough.
Whatever API this is using, there's zero reason to show any information about the request other than "we didn't die, so it should succeed". Beyond even showing it, there's zero reason for a password reset API to respond to the request with the secret at all. If it needs to return anything identifying about the request, it should be some identifier that is NOT the secret, which can be used to pull up general info about the request later if needed (time generated, whether it was used, is it expired, etc). Extra points if the access credentials to any back-end API the request page uses can't even request the secret key from a request.
A sane API makes it very hard for something like this to happen. Often that takes an inversion of thinking, so instead of making an API as useful as possible and return as much data as efficiently as possible, you make to make it as secure as possible, which means returning as little data as possible to satisfy the specific needs of the use case, and different locked down credentials for specific use cases.
That’s why doing pen tests on the regular is necessary. We shouldn’t rely on humans getting it right every time, or strangers on the internet reporting it.
From experience I noticed that a lot of developers don't look at the big picture and don't have a full understanding of how the system works, what's the rationale behind how the feature achieved its objective and how it might be abused by a malicious user. The #1 thing that I think about when I'm looking at some code or feature (and recommend others do the same) is how malformed or intentionally malicious input would break it, but it seems like their developers clearly didn't do so.
This is also compounded by the drive to artificially complicate software stacks (microservices, etc) and "silo" developers into their own little bubble where they only work on a small aspect of the system and never have a need (nor the mental capacity - due to intentionally complicated stacks with dozens of microservices in various languages) to look at the big picture.
But seriously, I'm sure it was made by people that just didn't stop to think about security and "it works, so we're done here" Then, as a business you're not going to try and fix it if the software already works. That would be pure cost.
At some point, a different developer was told to consume this endpoint, send the related email, and tell the end user (browser client) that the email was sent. This second developer is not part of the "senior services team" who designed the above API, which is perfectly valid. Instead, this is a junior developer taking on their first task at the company. "Take this password reset API endpoint, and integrate it". In addition to queuing the password reset email with the token embedded within it, they also accidentally proxy the password reset service's payload to the browser. No intermediate or senior develop reviewed this new employee's PR; if they did bother to look at it, they only checked for coding standard violations (eg. indentation), without taking the effort to understand the logic of the code.
This is actually extremely common, unfortunately. The server-side layer that directly interacts with clients (ie. browsers) is generally delegated to the most junior developers, because it's menial and uninteresting work to connect the backend services to the browser. The current senior developers spent years working on that kind of garbage already, and they'd rather work on the "more interesting/advanced" backend work. Thus, the junior developers whose skills aren't yet honed are stuck–typically unsupervised–working on the front-facing components.
Also, this routinely happens at companies which rush every feature out the door with modern "agile" practices. The sprint is almost over! Quick, deliver all features by tomorrow to keep up our velocity and avoid a sprint review with negative feedback! Just merge it and push to prod without QA on a Friday at 4pm!
If only the above was a comedy routine, rather than what it truly is: the genuine reality at a large number of companies.