Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
require 'core_extensions/string/permit'

class ApplicationController < ActionController::Base
String.include CoreExtensions::String::Permit
include UserSessionContext
include VerifyProfileConcern
include LocaleHelper
Expand Down
2 changes: 0 additions & 2 deletions app/controllers/sign_up/email_resend_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module SignUp
class EmailResendController < ApplicationController
include UnconfirmedUserConcern

def new
@user = User.new
@resend_email_confirmation_form = ResendEmailConfirmationForm.new
Expand Down
18 changes: 18 additions & 0 deletions lib/core_extensions/string/permit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# When a controller uses Strong Parameters such as:
# params.require(:user).permit(:email), the `user` param is assumed to
# be a Hash, but it's easy for a pentester (for example) to set the
# `user` param to a String instead, which by default would raise a 500
# error because the String class doesn't respond to `permit`. To get
# around that, we monkey patched the Ruby String class to raise an
# instance of ActionController::ParameterMissing, which will return
# a 400 error. 500 errors can potentially page people in the middle of
# the night, whereas 400 errors don't.
module CoreExtensions
module String
module Permit
def permit(*)
raise ActionController::ParameterMissing, '#permit called on String'
end
end
end
end
8 changes: 6 additions & 2 deletions spec/requests/invalid_sign_in_params_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
require 'rails_helper'

describe 'visiting sign in page with invalid user params' do
it 'does not raise an exception' do
get new_user_session_path, params: { user: 'test@test.com' }
it 'raises ActionController::ParameterMissing' do
params = { user: 'test@test.com' }
message_string = 'param is missing or the value is empty: #permit called on String'

expect { get new_user_session_path, params: params }.
to raise_error(ActionController::ParameterMissing, message_string)
end
end

Expand Down
30 changes: 30 additions & 0 deletions spec/requests/params_is_string_instead_of_hash_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'rails_helper'

# When a controller uses Strong Parameters such as:
# params.require(:user).permit(:email), the `user` param is assumed to
# be a Hash, but it's easy for a pentester (for example) to set the
# `user` param to a String instead, which by default would raise a 500
# error because the String class doesn't respond to `permit`. To get
# around that, we monkey patched the Ruby String class to raise an
# instance of ActionController::ParameterMissing, which will return
# a 400 error. 500 errors can potentially page people in the middle of
# the night, whereas 400 errors don't.
describe 'submitting email resend form with required param as String' do
it 'raises ActionController::ParameterMissing' do
params = { resend_email_confirmation_form: 'abcdef' }
message_string = 'param is missing or the value is empty: #permit called on String'

expect { post sign_up_create_email_resend_path, params: params }.
to raise_error(ActionController::ParameterMissing, message_string)
end
end

describe 'submitting email registration form with required param as String' do
it 'raises ActionController::ParameterMissing' do
params = { user: 'abcdef' }
message_string = 'param is missing or the value is empty: #permit called on String'

expect { post sign_up_register_path, params: params }.
to raise_error(ActionController::ParameterMissing, message_string)
end
end