guest@websec ~ % man 19-misconfiguration-and-errors
19 · Misconfiguration and Error Handling
Misconfiguration is now #2 on the OWASP list, and "mishandling errors" is new. Both are about stuff around the code: what's left on, what's exposed, what happens when things fail.
19.1 Security misconfiguration
What auditors usually find:
- Debug mode in production, showing stack traces to anyone.
- Dashboards (jobs, feature flags, DB tools) with no login.
- Default or shared credentials on databases, admin panels and third-party tools.
- Files that shouldn't be public:
/.git/,.env, backups (db.sql.gz), editor swap files, source maps with secrets. - Cloud storage buckets readable (or writable) by everyone.
exposure:
Rails' production defaults are good: no debug pages, no web console. The usual gaps are ours: mounting Sidekiq, Mission Control or Flipper without auth, or running in development mode on a public server.
# config/routes.rb: every dashboard behind an admin constraint authenticate_admin = ->(req) { Session.find_by(id: req.cookie_jar.signed[:session_id])&.user&.admin? } constraints(authenticate_admin) do mount Sidekiq::Web => "/sidekiq" mount MissionControl::Jobs::Engine => "/jobs" mount Flipper::UI.app(Flipper) => "/flipper" end # config/environments/production.rb (verify these) config.consider_all_requests_local = false # generic error pages config.force_ssl = true config.hosts = ["app.example.com"] config.log_level = :info # :debug can log SQL with values
19.2 Mishandling exceptional conditions
This is about what happens when things go wrong. Three patterns do most of the damage:
Failing open
If a security check errors, deny. Classic bug: the permission service times out, a broad rescue swallows it, and the code carries on as if allowed.
error handling:
Half-finished operations
A crash halfway can leave money debited but not credited. Wrap related writes in a transaction.
Leaky or missing error handling
- Show users a simple message with a reference ID. Keep the details in your logs.
- Put limits on anything that can grow: uploads, page sizes, timeouts.
- A bare
rescue => earound security code is a red flag.
Transactions roll back on errors, and
Rails.error.report sends errors to your tracker. Failing closed, and timeouts on outbound calls (default 60 s!), are on us.def destroy
customer = Customer.find(params[:id])
return head :forbidden unless allowed_to_delete?(customer)
customer.destroy!
end
private
def allowed_to_delete?(customer)
PermissionService.allowed?(Current.user, :delete, customer)
rescue PermissionService::Timeout => e
Rails.error.report(e, context: { customer_id: customer.id })
false # fail CLOSED
end
rescue StandardError then true # fail OPEN: any error grants access
# all-or-nothing writes
ActiveRecord::Base.transaction do
from.lock!.update!(balance: from.balance - amount)
to.lock!.update!(balance: to.balance + amount)
end
Net::HTTP.start(host, 443, use_ssl: true, open_timeout: 2, read_timeout: 5) { … }