LostKobrakai

LostKobrakai

After having watched the talk I’m wondering if this would also be a good opportunity to gather examples / tips about how to prevent or mitigate the mentioned issues. I’d expect the e.g. for the mentioned session issue there might already be examples out there. Also I’m especially curious about the last topic on mass assignment. How do you guys handle changesets which are allowed to change things like admin flags or alike, so at best they’re not accidentally usable from any frontend forms.

Showing Posts 1 to 10

griffinbyatt

griffinbyatt

I’ll comment with some of my thoughts a bit later when I have some more time. Until then, I wanted to say thanks for posting, and I’m happy to answer questions about the content if anyone has any!

LostKobrakai

LostKobrakai OP

I’ll start by adding my captain obvious solution to prevent accidental changes to admin flag fields: Don’t handle it through the params sent to changeset/2, but only allow them to be changed by custom functions.

def make_admin(%User{} = user) do
  user
  |> Ecto.Changeset.change(%{is_admin: true})
  |> Repo.update()
end

def put_admin_flag(%Ecto.Changeset{} = changeset) do
  Ecto.Changeset.change(changeset, %{is_admin: true})
end

This way in each places, where setting that flag should indeed be possible it has to be done explicitly, independent to any changeset/2 functions/params.

griffinbyatt

griffinbyatt

The nice thing about most of the vulnerabilities I talked about is that Phoenix does a good job of pushing you in the right direction, so there often aren’t too many ways to make mistakes. This means that 1) Once you are aware of the issues, they become much easier to avoid, and 2) A lot of these issues are easy to detect in an automated fashion, so a tool like Sobelow can simply/reliably help you avoid them.

That leaves “logical” issues like session/auth handling and “mass assignment” type vulns. These tend to be less Phoenix-specific, and are common across applications. Mass Assignment vulnerabilities are a pretty classic Rails issue, and have been fairly highly publicized, but the Rails community still has issues with it. It’s a pretty hard thing to mitigate.

I think part of the problem people have w/ the changeset functionality is that, because the changeset function is generated for you (and because it’s called “changeset”), the changeset function feels very “official” and safe.

^^ This is definitely a solid way to start dealing with sensitive fields! Another is to have a bunch of unique, very explicit changesets. E.g. registration_changeset, admin_changeset.

Also, when possible, explicitly passing params is a good move. For example, something like:

User.registration_changeset(%{email: email, username: username})

People tend to like this recommendation less b/c it can cause a lot of duplication. But I like it, because even if something unfortunate changes w/in the changeset function, you’re still safe :stuck_out_tongue:

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

One person’s duplication is another’s de-coupling. :slight_smile:

sillypog

sillypog

I am trying out this approach to the “mass assignment” issue. I haven’t merged it in to my project yet so this is a good time for feedback :slight_smile:

I have a plug called WhitelistParams that takes the name of the parameter to be filtered, and a list of acceptable fields for that param. So my UserController has this at the top:

plug WhitelistParams, %{param: "user", list: User.public_fields} when action in [:update]

User exposes its public_fields through a function which returns the @public_fields module attribute. The @allowed_fields attribute is a concatenation of the @public_fields and @private_fields arrays. I can certainly see an argument that the public_fields list is not the responsibility of the model but it seemed convenient since the fields must be listed in the model for casting changesets.

OvermindDL1

OvermindDL1

@sillypog

Good idea, do you have a hex package up of it, or want to PR it to Plug? :slight_smile:

sillypog

sillypog

I don’t yet. Assuming our team merges it, I’ll see how it goes here and apply it in some other cases. If it is easy to work with then I will put something together. I think there will be some edge cases in terms of handling parameters of different types - right now I’ve only tried it on a single map, such as:

{
  "user": {
    "field1": "value1",
    "field2": "value2"
  }
}
michalmuskala

michalmuskala

That’s exactly what changeset does, just as a plug rather than part of ecto, right?

sillypog

sillypog

I think in the case of the User I have some fields that should not be available to the update route, but do need to make it into the changeset from other places. For example, User has a password_reset_code field that is set by a changeset, but I don’t want that field to be editable by passing it into update. Filtering that out in the controller seemed like the best solution.

sillypog

sillypog

I think it is working the same way as changesets. It takes only the whitelisted fields from the map and replaces the existing param with those.

def call(%{:params => params} = conn, %{param: param_name, list: list}) do
  filtered_params = Map.take(params[param_name], list)
  merged_params = Map.put(params, param_name, filtered_params)
  %{conn | params: merged_params}
end

Nothing too fancy.

Where Next? Top

Trending in Talks Top

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews