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

CodeSync
LT: Skode: an ASCII shorthand for audio experimentation - Joseph Stewart | ElixirConf EU 2026 Comments welcome! View the ...
New
CMC
How to Think About Game Servers (Pt 2) Hernán Rivas Acosta looks at how latency and jitter affect multiplayer games and the techniques d...
New
ElixirConf
Lightning Talk: Kate Rezentes - Notion-land | ElixirConf US 2025 https://www.youtube.com/watch?v=nLWm8gIz8TI Comments welcome! View th...
New
ElixirConf
Lightning Talk: Vito - An Absurd Situation with EPMD | ElixirConf US 2025 Comments welcome! View the <span class="hashtag...
New
ElixirConf
Lightning Talk: Ivy Markwell - Data migrations with Monarch | ElixirConf US 2025 https://www.youtube.com/watch?v=AF1z6Z3bJKY Comments ...
New
CodeSync
Testing Concurrency and Fault Tolerance in Elixir/Nerves - Marta Habdas | ElixirConf EU 2026 Comments welcome! View the <...
New
CodeSync
Practical Data Orchestration in Elixir - Silvia Zeamer | ElixirConf EU 2026 Comments welcome! View the <span class="hasht...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
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
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews