diff --git a/routes/admin.rb b/routes/admin.rb index 9b7d6f25..c26b27cf 100644 --- a/routes/admin.rb +++ b/routes/admin.rb @@ -3,6 +3,28 @@ config_options = JSON.parse(File.read('./config.json')) +#Class for password Complexity Checking +class Password_Complexity + attr_reader :counter + def initialize(check_pass) + @counter = 0 + @check_pass = check_pass + if @check_pass =~ /(?=.*?[a-z])/ + @counter += 1 + end + if @check_pass =~ /(?=.*?[A-Z])/ + @counter += 1 + end + if @check_pass =~ /(?=.*?[0-9])/ + @counter += 1 + end + if @check_pass =~ /[^a-z^A-Z^0-9]/ + @counter += 1 + end + @check_pass = "passwordCleared" + end +end + # set the report_assessment_types for <1.2 versions of Serpico unless config_options['report_assessment_types'] config_options['report_assessment_types'] = ['Network Internal', 'External', 'Web application', 'Physical', 'Social engineering', 'Configuration audit'] @@ -74,26 +96,37 @@ user = User.first(username: params[:username]) - if user - if params[:password] && (params[:password].size > 1) - # we have to hardcode the input params to prevent param pollution - user.update(type: params[:type], auth_type: params[:auth_type], password: params[:password]) + #Check Password Length + unless params[:password].size >= 12 + return 'Srsly? Your password must be at least 12 characters in length.' + end + + #Check Password Complexity + pwd_counter = Password_Complexity.new(params[:password]) + if pwd_counter.counter <= 2 + return 'Passwords must contain at least 3 of the following: numbers, uppercase, lowercase, and symbols.' + else + #All good, carry on. + if user + if params[:password] && (params[:password].size > 12) + # we have to hardcode the input params to prevent param pollution + user.update(type: params[:type], auth_type: params[:auth_type], password: params[:password]) + else + # we have to hardcode the params to prevent param pollution + user.update(type: params[:type], auth_type: params[:auth_type]) + end else - # we have to hardcode the params to prevent param pollution - user.update(type: params[:type], auth_type: params[:auth_type]) + user = User.new + user.username = params[:username] + user.password = params[:password] + user.type = params[:type] + user.auth_type = params[:auth_type] + user.save end - else - user = User.new - user.username = params[:username] - user.password = params[:password] - user.type = params[:type] - user.auth_type = params[:auth_type] - user.save + serpico_log("User #{user.username} created") + redirect to('/admin/list_user') end - - serpico_log("User #{user.username} created") - redirect to('/admin/list_user') -end +end get '/admin/list_user' do redirect to('/no_access') unless is_administrator? diff --git a/routes/basic.rb b/routes/basic.rb index dbf540f3..664510a6 100644 --- a/routes/basic.rb +++ b/routes/basic.rb @@ -3,6 +3,27 @@ config_options = JSON.parse(File.read('./config.json')) +class Password_Complexity + attr_reader :counter + def initialize(check_pass) + @counter = 0 + @check_pass = check_pass + if @check_pass =~ /(?=.*?[a-z])/ + @counter += 1 + end + if @check_pass =~ /(?=.*?[A-Z])/ + @counter += 1 + end + if @check_pass =~ /(?=.*?[0-9])/ + @counter += 1 + end + if @check_pass =~ /[^a-z^A-Z^0-9]/ + @counter += 1 + end + @check_pass = "passwordCleared" + end +end + # Used for 404 responses not_found do "Sorry, I don't know this page." @@ -105,16 +126,28 @@ return 'You are an LDAP user. You cannot change your password.' end - # check if the password is greater than 3 chars. legit complexity rules =/ - # TODO add password complexity requirements - if params[:new_pass].size < 4 - return 'Srsly? Your password must be greater than 3 characters.' + #Check Password Minimum Length (Default: 12 characters) + unless params[:new_pass].size >= 12 + return 'Srsly? Your password must be at least 12 characters in length.' + end + + #Check Password Complexity + pwd_counter = Password_Complexity.new(params[:new_pass]) + if pwd_counter.counter <= 2 + return 'Passwords must contain at least 3 of the following: numbers, uppercase, lowercase, and symbols.' + end + + #Check that new password doesn't match old password + if params[:new_pass] == params[:old_pass] + return 'New password cannot be the same as the old password.' end + #Prevent fat fingers, check password against confirmation entries if params[:new_pass] != params[:new_pass_confirm] return 'New password does not match.' end + #Check for current password unless User.authenticate(user.username, params[:old_pass]) return 'Old password is incorrect.' end diff --git a/views/add_user.haml b/views/add_user.haml index adc940b5..7d60bc58 100644 --- a/views/add_user.haml +++ b/views/add_user.haml @@ -3,6 +3,15 @@ %h1.h2 Edit User - else %h1.h2 Add User +.d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-center.pt-3.pb-2.mb-0.border-top + Password must be a minimum 12 characters in length. + %br + Password must contain three out of the four following categories: +.d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-center.pt-0.pb-0.mb-0 + %form{ :method => "post", :action => "/admin/add_user" } .form-group.row diff --git a/views/reset.haml b/views/reset.haml index 4967af53..133d53b2 100644 --- a/views/reset.haml +++ b/views/reset.haml @@ -4,6 +4,16 @@ - else .d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-center.pt-3.pb-2.mb-3.border-bottom %h1.h2 Change Password + .d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-left.pt-0.pb-3 + Password must be a minimum 12 characters in length. +
+ Password must contain three out of the four following categories: + .d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-left.pt-0.pb-3 + %form{ :method => "post" } .form-group.row