Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực

Phần một series cover Injection Attacks

Trong bài hai series về OWASP Top 10 Web Application Security Risks, chúng ta dive vào universe broken authentication và data exposure threats.

Cụ thể, nói về việc hacker dễ dàng trick code bạn built và perform attacks obtain users’ data:

  • User enumeration: Khi exploit login pages bằng brute-force testing list possible users check exist database.
  • Weak passwords: Khi system allow weak passwords, hackers brute force attack guess users' passwords.
  • Unrestricted cookies: Khi system store sensitive data cookies without proper security settings, hackers steal information through XSS attacks.

Chúng ta cũng go into detail sensitive data không sufficiently protected, making room vulnerabilities:

  • Unsafe sensitive storage: khi sensitive data encrypted weak algorithms như MD5.
  • Exposing sensitive data: khi developers unintentionally expose unencrypted sensitive data URLs hoặc hidden fields.

Giống bài đầu series, dùng RailsGoat explore each threats in practice. Nếu mới, refer previous article setup app running.

Let's jump right in!

Authentication Threats

Không thể sống không authentication. Dù back-end APIs hay front-end forms, đó là one of most important steps application development vì highlight border limits security measures.

Không chỉ authentication mà session management. Where store passwords và tokens? Properly encrypted? Trustworthy algorithm? Password complex enough?

Nhiều questions keep eye on. Break down và understand common attacks involving authentication và session management trong Rails applications.

User Enumeration

User enumeration là famous technique attackers dùng check (via brute force) whether given data exist within system.

Notorious examples attack happens current Facebook login page. Enter invalid random credentials như image dưới, Facebook process request check existence user within database.

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Facebook's login page.

Click Log In button, Facebook return error message stating username (email hoặc phone number) isn't valid.

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Invalid username message.

Do đó, attacker biết application tells you whether user registered. For free.

Nếu attacker có list emails (random generated hoặc bought), also possible ask application whether password correct:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Invalid password message.

Khi attacker biết system responds separately each validation, list tạo possible users và common/weak passwords. Brute-force tests conducted repeatedly against system until access gained.

Chắc chắn Facebook developers biết, implement additional protections: invisible captchas và validations over number requests từ specific IP address.

Một thing you can do avoid user enumerations: validate both username và password together và return generic message. Xem approach in action!

The Threat In Action

Trong RailsGoat app, open user.rb file in app/models folder locate authenticate method. Within it, find code snippet:

raise "#{email} doesn't exist!" if !(user)
if user.password == Digest::MD5.hexdigest(password)
  auth = user
else
  raise "Incorrect Password!"
end

Exactly! Messages set cách cho attackers know whether user doesn't exist hoặc password incorrect.

Test it out. Go to RailsGoat login page type random email và password. May see error message:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực The user doesn't exist.

Otherwise, nếu user exists (ken@metacorp.com, example) nhưng password wrong, message displayed:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Incorrect password.

Considering app only allows strong passwords, attacker still create list enumerated valid client emails và target phishing emails to them, creating impression you're requesting malicious action.

How To Resolve This Issue

Quickest action make it safer: change message và complicate hacker's life.

Trong sessions_controller.rb (app/controllers folder), locate create method change code snippet

flash[:error] = e.message

to:

flash[:error] = "Your credentials aren't valid."

Giờ, every time users type wrong username hoặc password, that's message they'll receive:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Invalid credentials.

Another way: change two messages trong users.rb model.

Weak Passwords

Không stress enough. Require users input strong passwords và create validation code check whether meet criteria strong password.

One of most important steps prevent user enumerations.

The Threat In Action

Trong RailsGoat, open user.rb file locate first line code right before class definition:

validates :password, presence: true, confirmation: true, length: { within: 6..40 }, ...

Clear example password weakly validated vì chỉ length checked.

How To Resolve This Issue

Solution simple: validate password against stronger requirements:

  • at least 1 lowercase và 1 uppercase letter,
  • at least 1 digit,
  • at least 10 chars.

More requirements add, safer passwords. Just sure not push too much vì complexity increase usability và password recovery flow.

Solve within RailsGoat, substitute length property với:

:format => {:with => /\A.*(?=.*[a-zA-Z])(?=.*[0-9])(?=.{10,}).*\z/},

Sau đó, go to sign-up page, fill fields, provide weak password. Submit, error message displayed:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực The password is invalid.

Unrestricted Cookies

Bài trước, dedicated time understand XSS attacks occur. Vì take place bằng cách allow attackers run malicious scripts, important information stolen from session cookies nếu không prevent access attributes, như document.cookie trong JavaScript code.

Remember dispute Web storage vs. cookies often discussed community. Web storage more practical, attacker gain full access objects stored there without proper protection XSS threats.

Cookies, turn, bit safer nếu take right steps make them so, như setting HttpOnly flag.

In short, cookie holds session information và set with HttpOnly flag can't be accessed từ JavaScript Document.cookie API. This way, only server receive it.

Alternatively, cũng có Secure attribute, ensure cookie only sent server nếu (and only if) request happens within HTTPS (never HTTP). Makes requests safer case someone sniffing as man-in-the-middle.

The Threat In Action

Rails take step for you bằng automatically setting all cookies with HttpOnly flag. Great vì helps unaware developers avoid apps hacked.

Test example, disable feature, RailsGoat explicitly did trong session_store.rb file, located config/initializers folder. Check it out!

Sau đó, go to registration page once more, fill fields properly, input following content into Name field:

<script> alert(document.cookie); </script>

Khi submit form, user created, along subsequent alert message:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Alert message exposing RailsGoat session cookie.

How To Resolve This Issue

Case này straightforward, just make sure not disable HttpOnly flag on Rails apps.

Remove httponly: false setting và restart server. Khi try same operation, alert message displayed:

Rails Security: Phòng Thủ Lỗ Hổng Xác Thực Empty alert message.

Other Scenarios

Imagine accessing Web application từ computers không secure, như public library computers hoặc LAN houses. Nếu application không configured properly log you out sau specified period inactivity, session still there.

Simply closing browser tab isn't enough log out application.

Another common issue developers’ code: expose IDs any kind front end. Not hard think scenarios keeping user's ID hidden input hoặc URL makes life easier khi user further requests something else server.

However, this halfway through stealing attack.

Sensitive Data Exposure

Topic này perhaps one of most underestimated dedicating enough effort ensure security sensitive information.

Whether data constant transit hoặc at rest, extremely important separate ordinary data từ sensitive data. Sensitive data include credit card numbers và codes, passwords, personal identifier numbers, hoặc anything relates compliance hoặc privacy laws (như EU's GDPR và PCI).

Other than that, depending specific business area app running, important consult local legislation determine whether other compliance rules also apply.

Clear examples vulnerability:

  • Data somehow encrypted hoặc transported as plain text through Web?
  • Encrypt data, algorithm gì? Strong và reliable against newest crypto attacks?
  • Use default cryptographic keys nếu none provided?
  • Checked whether HTTP requests enforced proper security headers?

Analyze common scenarios.

Unsafe Sensitive Storage

Nếu worked Web applications một thời gian, chances heard about (hoặc used) MD5 message-digest algorithm. Dù still widely used hashing passwords, proven extremely weak.

Important understand difference hashing và encrypting information. Encryption supposed happen khi key used decrypt data. Hashing refers to method conversion; turn data into hash but not vice versa.

Applies all sorts sensitive information, although MD5 mostly known used password hashing. Nếu app keeps user's Social Security Number (SSN), example, sure not only store safely within database mà watch how data transmitted through app to other databases, especially browser.

The Threat In Action

Như seen, RailsGoat purposely stores user's password as MD5 hashes. Xem trong user.rb model:

def hash_password
  if self.password.present?
    self.password = Digest::MD5.hexdigest(password)
  end
end

Every time user logs in, app hashes provided password check whether results equal. Otherwise, passwords not match, error thrown.

How To Resolve This Issue

Nhiều ways tackle issue, nhưng perhaps most famous through salt hashes, như BCrypt provides.

Mặc dù Rails comes default capabilities deal Bcrypt, notorious lib widely used: bcrypt-ruby:

gem install bcrypt

Khi map model với nó, how password set và obtained from database defined. Lib adapts everything else automatically:

require 'bcrypt'
class User < ActiveRecord
  include BCrypt
  def password
    @password ||= Password.new(password_hash)
  end
  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end
end

Tuy nhiên flow requires additional string column (password_hash) at table store password hash BCrypt algorithm.

Way này, set password value directly model object, BCrypt take care securely hashing. Same happens khi password retrieved compare với user's input.

Exposing Too Much

Dù working REST APIs hoặc GraphQL endpoint, example, sure return only necessary make client work.

Nếu JavaScript client requests information từ API và uses only portion, không impede attacker grabbing endpoint calling again retrieve whole response hoặc sniff với proxy tool.

Always review APIs certify rằng regardless sensitive information returned, only do so với proper encryption và right places.

The Threat In Action

Khi comes user's data, important create secure mechanisms ensure sensitive information won't be leaked.

Open users_controller.rb file in api/v1 folder. There, find method:

def show
  respond_with @user.as_json
end

Simple as it is, khi accessed by Web client, endpoint return all user's fields populated within response, including password.

Not only user model mà other models hold sensitive information cần way select attributes visible to APIs.

How To Resolve This Issue

May mắn, Rails provides very easy way deal with it. Override as_json method với:

def as_json
  super(only: [:id, :email])
end

Giờ, thay vì expose everything default, chỉ respond required data. Each model, sure select important fields và apply same rule of thumb.

Wrapping Up

Hôm nay, navigated through waters broken authentication và sensitive data exposure. Following these rules, surely guarantee much safer application cho users và clients.

Additionally, importance going through official Ruby on Rails Security Documentation can't be overemphasized. There, may find more information session hijacking, storage mechanisms, strategies encrypt data best way possible.

See you at our next stop!