Skip to content

Commit

Permalink
Security (#10)
Browse files Browse the repository at this point in the history
fidati di dio, ma prima lega il cavallo
baldarn authored Aug 30, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 227b03b commit 5761e01
Showing 13 changed files with 111 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# conf for docker compose

PG_PORT=8001
REDIS_URL=redis://localhost
REDIS_PORT=8002

# kamal version hack for github deployment

5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ gem 'rails', '~> 7.2.0'

# Drivers
gem 'pg', '~> 1.5.7'
gem 'redis', '~> 5.3'
gem 'sqlite3', '~> 1.4'

# Deployment
@@ -33,6 +34,10 @@ gem 'simple_form', '~> 5.3'
gem 'stimulus-rails'
gem 'turbo-rails'

# Security
gem 'rack-attack'
gem 'rucaptcha'

# Pagination
gem 'kaminari'
gem 'kaminari-i18n'
25 changes: 25 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -295,6 +295,8 @@ GEM
raabro (1.4.0)
racc (1.8.1)
rack (3.1.7)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
rack-session (2.0.0)
rack (>= 3.0.0)
rack-test (2.1.0)
@@ -336,9 +338,14 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.2.1)
rb_sys (0.9.102)
rdoc (6.7.0)
psych (>= 4.0.0)
redcarpet (3.6.0)
redis (5.3.0)
redis-client (>= 0.22.0)
redis-client (0.22.2)
connection_pool
regexp_parser (2.9.2)
reline (0.5.9)
io-console (~> 0.5)
@@ -377,6 +384,21 @@ GEM
ruby-vips (2.2.1)
ffi (~> 1.12)
rubyzip (2.3.2)
rucaptcha (3.2.3)
railties (>= 3.2)
rb_sys (>= 0.9.86)
rucaptcha (3.2.3-aarch64-linux)
railties (>= 3.2)
rb_sys (>= 0.9.86)
rucaptcha (3.2.3-arm64-darwin)
railties (>= 3.2)
rb_sys (>= 0.9.86)
rucaptcha (3.2.3-x86_64-darwin)
railties (>= 3.2)
rb_sys (>= 0.9.86)
rucaptcha (3.2.3-x86_64-linux)
railties (>= 3.2)
rb_sys (>= 0.9.86)
sassc (2.4.0)
ffi (~> 1.9)
sassc-rails (2.1.2)
@@ -500,14 +522,17 @@ DEPENDENCIES
mission_control-jobs (~> 0.3.1)
pg (~> 1.5.7)
puma (>= 5.0)
rack-attack
rails (~> 7.2.0)
rails-i18n (~> 7.0.0)
redcarpet (~> 3.6)
redis (~> 5.3)
rouge (~> 4.2)
rqrcode
rubocop (~> 1.65)
rubocop-capybara
rubocop-rails
rucaptcha
sassc-rails
selenium-webdriver
simple_calendar
10 changes: 9 additions & 1 deletion app/controllers/users/registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -13,6 +13,14 @@ class RegistrationsController < Devise::RegistrationsController

# POST /resource
def create
build_resource(sign_up_params)
# TODO: fix this in tests
if !Rails.env.test? && !verify_rucaptcha?(nil, captcha: params[:user][:_rucaptcha])
clean_up_passwords resource
resource.errors.add(:_rucaptcha, '')
return respond_with resource
end

params[:user][:registering] = true
super

@@ -65,7 +73,7 @@ def configure_sign_up_params
devise_parameter_sanitizer.permit(
:sign_up,
keys: %i[first_name last_name registering club_name club_email club_address club_postal_code club_municipality
club_province club_tax_code club_telephone]
club_province club_tax_code club_telephone _rucaptcha]
)
end

2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ class User < ApplicationRecord
-> { where(blsd_expires_at: Time.zone.today.beginning_of_day..6.months.from_now) }

attr_accessor :registering, :club_name, :club_email, :club_address, :club_postal_code,
:club_municipality, :club_province, :club_tax_code, :club_telephone
:club_municipality, :club_province, :club_tax_code, :club_telephone, :_rucaptcha

validates :club_name, :club_email, :club_address, :club_postal_code, :club_municipality, :club_province,
:club_tax_code, presence: true, if: -> { registering == true }
10 changes: 10 additions & 0 deletions app/views/devise/registrations/new.html.erb
Original file line number Diff line number Diff line change
@@ -15,6 +15,16 @@
<%= f.input :club_telephone, autofocus: true %>
<%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length), input_html: { autocomplete: "new-password" } %>
<%= f.input :password_confirmation, required: true, input_html: { autocomplete: "new-password" } %>
<%= f.input :_rucaptcha, required: true do %>
<div class="row">
<div class="col-sm-6">
<%= f.input_field :_rucaptcha, name: 'user[_rucaptcha]', class: 'form-control' %>
</div>
<div class="col-sm-4">
<a class="rucaptcha-image-box" href="#"><%= rucaptcha_image_tag(alt: 'Captcha') %></a>
</div>
</div>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit, "Sign up" %>
13 changes: 7 additions & 6 deletions config/deploy.yml
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ registry:
env:
clear:
PG_HOST: host.docker.internal
REDIS_URL: redis://host.docker.internal
APP_HOST: opengas.eu
SMTP_PORT: 587
SMTP_ADDRESS: smtp.ionos.it
@@ -72,12 +73,12 @@ accessories:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
# redis:
# image: redis:7.0
# host: 192.168.0.2
# port: 6379
# directories:
# - data:/data
redis:
image: redis:7.4
host: opengas.eu
port: 6379
directories:
- data:/data

# Configure custom arguments for Traefik. Be sure to reboot traefik when you modify it.
traefik:
6 changes: 5 additions & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
@@ -25,7 +25,9 @@
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true

config.cache_store = :memory_store
config.cache_store = :redis_cache_store, {
url: "#{ENV.fetch('REDIS_URL', 'redis://localhost')}:#{ENV.fetch('REDIS_PORT', '6379')}/0"
}
config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{2.days.to_i}" }
else
config.action_controller.perform_caching = false
@@ -84,3 +86,5 @@
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
config.generators.apply_rubocop_autocorrect_after_generate!
end

Rack::Attack.enabled = false
4 changes: 3 additions & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
@@ -68,7 +68,9 @@
# want to log everything, set the level to "debug".
config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info')

config.cache_store = :file_store, ENV.fetch('FILE_STORE', '/rails/file_store/cache')
config.cache_store = :redis_cache_store, {
url: "#{ENV.fetch('REDIS_URL', 'redis://localhost')}:#{ENV.fetch('REDIS_PORT', '6379')}/0"
}

# Use a real queuing backend for Active Job (and separate queues per environment).
config.active_job.queue_adapter = :solid_queue
2 changes: 2 additions & 0 deletions config/environments/test.rb
Original file line number Diff line number Diff line change
@@ -67,3 +67,5 @@
# Raise error when a before_action's only/except options reference missing actions.
config.action_controller.raise_on_missing_callback_actions = true
end

Rack::Attack.enabled = false
3 changes: 3 additions & 0 deletions config/initializers/rack_attack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

Rack::Attack.throttle('requests by ip', limit: 5, period: 2, &:ip)
33 changes: 33 additions & 0 deletions config/initializers/rucaptcha.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

RuCaptcha.configure do
# Custom captcha code expire time if you need, default: 2 minutes
self.expires_in = 10.minutes

# [Requirement / 重要]
# Store Captcha code where, this config more like Rails config.cache_store
# default: Read config info from `Rails.application.config.cache_store`
# But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]
# 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,并尝试用可以运行的方式,用于存储验证码字符
# 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
self.cache_store = :memory_store

# If you wants disable `cache_store` check warning, you can do it, default: false
# 如果想要 disable cache_store 的 warning,就设置为 true,default false
# self.skip_cache_store_check = true

# Chars length, default: 5, allows: [3 - 7]
# self.length = 5

# Enable or disable Strikethrough, default: true
self.line = false

# Enable or disable noise, default: false
# self.noise = false

# Set the image format, default: png, allows: [jpeg, png, webp]
# self.format = 'png'

# Custom mount path, default: '/rucaptcha'
# self.mount_path = '/rucaptcha'
end
6 changes: 6 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -12,3 +12,9 @@ services:
environment:
- POSTGRES_USER=opengas
- POSTGRES_PASSWORD=opengas

redis:
image: redis:7.4
restart: unless-stopped
ports:
- ${REDIS_PORT:-6379}:6379

0 comments on commit 5761e01

Please sign in to comment.