guest@websec: ~/websec/19-misconfiguration-and-errors — zsh — 100×40 by SaKKo ENTH code:

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.
sim: production config auditfix the findings, watch the exposure drop
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.

sim: the permission service is downfail open vs fail closed
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 => e around 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) { … }