-
-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: false positive on unpermitted parameters #3097
Conversation
Code Climate has analyzed commit 949121d and detected 0 issues on this pull request. View more on Code Climate. |
Thanks for working on this Paul. I spent a little time trying to understand this and this is tricky. Kudos to you for coming up with the solution. I also have a small idea I want to share: Could we do something like this? #base.rb
def fill_record(record, params, extra_params_keys: [], fields: nil)
...
if extra_params.present?
# get_key_value returns a hash of objects like permit does...but without permitting
record.assign_attributes params.get_key_value(extra_params_keys)
end We'll need to code up the Do you think something like this would work? |
I thought about it but changed my mind after checking the PS: I can think about 3 possible solutions to this: 1 - Maintaining a method that behaves like record.assign_attributes params.permit(extra_params, action_on_unpermitted_parameters: false) @adrianthedev and @binarygit WDYT about making a PR to rails with these changes? (need to be tested and improved, it's just a DRAFT commit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To-do:
- let's fill out this PR with what we spoke on the call
- let's PR to Rails to suport
permit_without_warnings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
…b.com:avo-hq/avo into fix/false_positive_on_unnpermitted_parameters
…b.com:avo-hq/avo into fix/false_positive_on_unnpermitted_parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just added a couple of comments with a brief change explanation
@@ -64,7 +64,7 @@ def handle | |||
private | |||
|
|||
def action_params | |||
params.permit(:authenticity_token, :resource_name, :action_id, :button, fields: {}) | |||
@action_params ||= params.permit(:id, :authenticity_token, :resource_name, :action_id, :button, fields: {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memoizing and permitting id
.
The id
is present when an action is clicked from a show page.
@@ -132,7 +132,7 @@ def set_reflection_field | |||
end | |||
|
|||
def attachment_id | |||
params[:related_id] || params.require(:fields).permit(:related_id)[:related_id] | |||
params[:related_id] || params.dig(:fields, :related_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require
and permit
is not really necessary here, we just want to access the related_id
@@ -200,7 +200,7 @@ def through_reflection? | |||
end | |||
|
|||
def additional_params | |||
@additional_params ||= params[:fields].permit(@attach_fields&.map(&:id)) | |||
@additional_params ||= params[:fields].slice(*@attach_fields&.map(&:id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applying permit
only on the attach_fields
would raise the error of the unpermitted parameters for the remaining parameters.
permit
is unnecessary here because fill_record
enures that only params that match attach_fields
ids will be sent to the record.
# TODO: fix "found unpermitted parameter: :user_id-dummy" | ||
# tags field passes a dummy param generated from a fake input which is always unpermitted | ||
with_temporary_class_option(ActionController::Parameters, :action_on_unpermitted_parameters, :log) do | ||
sleep 0.3 | ||
click_on "Run" | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a tags field will always raise the unpermitted error since it is generating a dummy param that isn't permitted anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 😄 . Thanks Paul!
@@ -2,7 +2,7 @@ | |||
<% | |||
classes = 'absolute inset-auto left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2' | |||
label = t 'avo.failed_to_load' | |||
src_url = params[:src].present? && !params[:src].starts_with?('http://') ? params.permit(:src).fetch(:src) : nil | |||
src_url = params[:src].present? && !params[:src].starts_with?('http://') ? params[:src] : nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's sanitize the src_url
below where we display it. There's a security advisory there.
lib/avo/resources/base.rb
Outdated
@@ -461,8 +461,12 @@ def fill_record(record, params, extra_params: [], fields: nil) | |||
|
|||
# Write the user configured extra params to the record | |||
if extra_params.present? | |||
# Pick only the extra params | |||
# params at this point are already permited, only need the keys to access them | |||
extra_attributes = params.slice(*flatten_keys(extra_params)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we params
to permitted_params
so it's clear to anyone who's reading this and wondering why we are slicing instead of permitting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a couple of pieces of feedback.
GG! Looking forward to not showing unpermitted params useless to users.
Thanks!
This PR has been merged into Please check the release guide for more information. |
Description
Fixes #3095
TLDR
This PR ensures that unnecessary and "false positive" warnings about unpermitted parameters are not raised by using only the
permit
strong parameters method where we're permitting. We were using the samepermit
method in places where permitting params weren't necessary and we could useslice
orextract!
Context
When configuring
self.extra_params
on a resource and submitting a form, thepermit
method is utilized in two distinct stages:In the Base Controller: All parameters, including both base and extra params, are processed through Strong Parameters, ensuring they are permitted.
On the Resource: When updating the record,
permit
is called again but only for the extra params. This step isolates these extra params from the combined base and extra params hash.Actual approach
Instead of using
permit
onparams
to select the extra parameters, we now useslice
, which returns only the specified extra parameters. In order to useslice
we need to pass only the keys fromextra_params
. That's safe since theparams
at this point are already permitted (by using also the hashes values from extra_params) and there is no chance to pick unpermitted ones.Previous approach
We temporarily disable the action on unpermitted parameters during this second call. This is necessary because
permit
is applied exclusively to the extra params, which means any base params are excluded and would otherwise trigger errors or logs for being unpermitted.This approach does not impact the rest of the application because the action on unpermitted parameters is only temporarily disabled within this specific context. After handling the extra parameters, we restore the original setting for handling unpermitted parameters.
Checklist: