-
Notifications
You must be signed in to change notification settings - Fork 247
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
Fixed security issue that would allow unpermitted params to be passed through #1051
Fixed security issue that would allow unpermitted params to be passed through #1051
Conversation
@defnull This should technically solve both issues - please take a look and let me know |
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.
This also needs "integration" test cases which go through the rails request pipeline and include parameters in both the query string and body of the request. (I'd recommend writing these in Minitest rather than Rspec so you can use the Testing Rails Applications document for reference, and so I can review them for correctness.
See this SO reply: https://stackoverflow.com/a/58018336 which notes that the RSpec requests stuff cannot simulate a request with both query and body parameters, and demonstrates how to provide both using the QUERY_STRING
parameter:
class CollectionsTest < ActionDispatch::IntegrationTest
test 'foo' do
post collections_path, { collection: { name: 'New Collection' } },
{ "QUERY_STRING" => "api_key=my_api_key" }
# this proves that the parameters are recognized separately in the controller
# (you can test this in you controller as well as here in the test):
puts request.POST.inspect
# => {"collection"=>{"name"=>"New Collection"}}
puts request.GET.inspect
# => {"api_key"=>"my_api_key"}
end
end
/&checksum=#{params[:checksum]}|checksum=#{params[:checksum]}&|checksum=#{params[:checksum]}/, '' | ||
) | ||
# Generate a new query string using only allowed params (cant use .to_query because it changes the order) | ||
check_string += request.query_parameters.except(:checksum).map { |k, v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v)}" }.join('&') |
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.
This doesn't fix the problem. The request.query_parameters
method (which is an alias to request.GET
) still only returns query parameters, not parameters in a post body.
The use of the CGI.escape
function might escape the parameters differently from how they were on the original request (for example, integrations may either use %20
vs +
to replace a space), which will cause the checksum to fail in some cases.
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.
query_parameters
does include parameters that are passed through the body.
It also reflects the same parameters that are passed to encode_bbb_uri
through this method here
def pass_through_params(excluded_params)
params.except(*(excluded_params + [:format, :controller, :action, :checksum]))
.to_unsafe_hash
end
It doesn't fully include the body but at the very least it makes the checksum check the same parameters that are passed through to BBB
Yep - working on tests now |
I do not think this would solve the reported issue at all:
But since we are discussing this in the open now, may I suggest a different solution? First, stop accepting The signature is only valid for the verbatim url-encoded raw string (minus the checksum parameter). Order and encoding is important. The simplest code that avoids user-controlled regular expressions (issue 2) may be: check_string = action_name.camelcase(:lower)
check_string += request.query_string.split("&").reject(|p| p.starts_with "checksum=").join("&") (untested). |
Actually looks like you guys are right - I could've sworn when I tested that query_parameters worked but now its not. Will try again with a different approach |
Note that the "join" API in BigBlueButton does support POST requests despite not being mentioned in the docs; removing support for |
Usually the written specification is what counts. Support for POST requests to e.g. /join should either be specified in the documentation, or removed from the implementation, as soon as possible (3.0?). Undefined behavior is dangerous, as we see here. If POST support needs to be kept, then |
By the way: Currently |
Description
Testing Steps
Screenshots (if appropriate):