Skip to content

Instantly share code, notes, and snippets.

@eliotsykes
Last active March 14, 2017 17:39
Show Gist options
  • Save eliotsykes/ab874411625a12c8366b7f9753480513 to your computer and use it in GitHub Desktop.
Save eliotsykes/ab874411625a12c8366b7f9753480513 to your computer and use it in GitHub Desktop.
API Controller method override to use HTTP Basic
# Further defences to consider adding:
# - Restrict access to permitted IP address(es)
# - Use rack-attack to throttle requests and prevent brute force
# attack attempts to determine correct username and password
# - Favor long, random username and password
class Api::V1::ResultsController < Api::ApiController
def update
...
end
private
# Overrides authenticate method so requests to the results API
# only use HTTP Basic Auth (instead of Token Auth as used in
# ApiController#authenticate)
def authenticate
authenticate_or_request_with_http_basic do |username, password|
# Protect against timing attacks:
# - See https://codahale.com/a-lesson-in-timing-attacks/
# - See https://thisdata.com/blog/timing-attacks-against-string-comparison/
# - Use & (do not use &&) so that it doesn't short circuit.
# - Use digests to stop length information leaking
ActiveSupport::SecurityUtils.secure_compare(
::Digest::SHA256.hexdigest(username),
::Digest::SHA256.hexdigest(results_api_username)
) &
ActiveSupport::SecurityUtils.secure_compare(
::Digest::SHA256.hexdigest(password),
::Digest::SHA256.hexdigest(results_api_password)
)
end
end
def results_api_username
ENV.fetch("RESULTS_API_USERNAME") { raise "Missing Results API username!" }
end
def results_api_password
ENV.fetch("RESULTS_API_PASSWORD") { raise "Missing Results API password!" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment