Hacker News new | past | comments | ask | show | jobs | submit login

Yep, so it's the classic Rails bug pattern.



A tiny little piece of Django design that I'm pleased to have participated in is this:

    emails = request.POST.getlist("email")
Django doesn't mix lists and single string values, because I'd been burned by that problem in PHP.


In php it would be trivial (and expected) to have a `string` type on a parameter that's expected to be a string - thus negating this issue.

But then using the email address from the request rather than the already verified address in the DB seems like a weird design decision to me anyway.


wait, what do you mean by in PHP?


Strong parameters has been a core security feature of rails for a long time, and all the guides go into detail about the boilerplate you need just to accept a form input past the strong parameter filters. It's weird to me that the pattern doesn't also include a "must he a string" option. I know you can add to_s everywhere, but making it part of the existing strong params would actually incentivise use.


It's weird, as I recall with strong params one of the only things it really makes you decide is whether a value is a scalar, array, or Hash. You can certainly allow a value to be scalar or array, but it's not very natural in strong params.

I mostly hate the way strong params gets used - it's a bad compromise between letting Ruby people do Ruby things and trying to plug up a category of vulnerability that's been biting rails apps for a decade. Now I do all my api definitions in openapi and it's way easier. I haven't tried it with a rails app but I think it'd work well there.


This is such a rarely used feature that I wonder if it would be helpful to have a CSP or preflight header that restricts the browser from sending multiple values for the same parameter.


It's a great feature that's been supported by browsers for decades. <select multiple> uses it. You can use it for checkboxes to select multiple items too.

If you changed it now you would break a whole lot of stuff.

I use it extensively in my own Datasette application, eg here: https://datasette.io/content/plugins?_facet=owner&_facet=is_...


You wouldn't need to change it. But if you made it a CORS header like Access-Control-Allow-Headers, then websites would be able to provide a default policy forbidding it so that their code that actually requires it would need to explicitly opt into the behavior.


But how would that affect a malicious actor deliberately invoking the behavior?


a browser is typically not used to exploit this class of bugs.


There is precedent for deputizing the browser to stop this kind of bug with Access-Control-Allow-Headers. If the backend wants to default to ignoring multiple GET/POST parameters with the same name, then the browser could helpfully fail to make a request that attempts to send them.


The attacker doesnt’t use a compliant browser to make the request. User agent protections only help in situations where a regular user (or their software) is being tricked


If you'd want to configure this you'd probably want it as some kind of configuration in the backend that disables it.


It's pretty commonly used in Rails form handling logic though, isn't it?


Hard to tell what the issue is without actually seeing the code.

If I had to guess what they did was:

  user = User.find_by(email: params[:emails])
  params[:emails].each { |email| send_recovery_email(user, email) }
Instead of:

  user = User.find_by(email: params[:emails])
  send_recovery_email(user, user.email) if user


It's open source, so we should be able to see the code?

Edit: Someone has digged it out: https://news.ycombinator.com/item?id=39162126


Properly used white list parameter controls (i.e., strong parameters) that are the default Rails behavior at this point would have prevented this bug completely.


This is a little like saying the best way to avoid this bug is to not have the bug. But that's true of all bugs. The C apologists used to say, "just bounds check properly!"


Content Security Policy is a User-Agent feature. The vulnerability here is server-side. A malicious actor exploiting this will be using their own HTTP client that does not respect a CSP.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: