Những bảo mật cần thiết trong ruby on rails
Bài đăng này đã không được cập nhật trong 7 năm
Những vấn đề liên quan đến bảo mật khi phát triển ruby on rails
Kiểm tra Unauthorized Access
Luôn xác minh người dùng được ủy quyền thự hiện những thao tác mà anh ta đang làm. Giả sử bạn có một trang với một danh sách các dự án mà người dùng sở hữu, một liên kết có thể là /projects/1
. Tuy nhiên, người dùng có thể dễ dàng chuyển đến một trang dự án khác bằng cách thay đổi 1 thành bất kỳ số nào.
Thay vì @project = Project.find(params[:id])
, bạn nên sử dụng@project = @current_user.projects.find(params[:id])
. Nếu dự án không thuộc về người đang sử dụng, kết quả cuối cùng sẽ trả về nil.
Xác thực (Authentication)
Để xác thực, bạn nên sử dụng một Gem có sẵn như devise hoặc authlogic. Nếu bạn tạo hệ thống xác thực của riêng bạn, hãy sử dụng built-in hass_secure_password của Rails. Devise và has_secure_password sử dụng bcrypt để băm mật khẩu. Nguyên tăc. không bao giờ lưu mật khẩu bằng văn bản rõ ràng. Lưu hash của mật khẩu thay vì mật khẩu thực. Khi xác thực người dùng, lấy mã băm của mật khẩu và so sánh nó với hash trên cơ sở dữ liệu.
Trong trường hợp một kẻ tấn công được truy cập vào cơ sở dữ liệu của bạn, anh ta sẽ cần tính toán mật khẩu có thể và so sánh nó với hash từ cơ sở dữ liệu của bạn. Bcrypt được thiết kế để được tính toán rất khó khăn vì vậy có thể mất một thời gian dài đấy .
Bộ lọc mật khẩu (Filter Password) và các Dữ liệu nhạy cảm khác trên log
Rails ghi lại tất cả các yêu cầu cho ứng dụng của bạn. Khi người dùng đăng nhập, tên người dùng và mật khẩu sẽ được đăng nhập trừ khi bạn lọc mật khẩu. Rails theo mặc định tạo ra config / initializers / filter_parameter_logging.rb
trong đó có
Rails.application.config.filter_parameters += [:password]
Chúng ta không lưu mật khẩu trong văn bản rõ ràng trên cơ sở dữ liệu và chúng ta cũng không muốn chúng xuất hiện trên các bản ghi (log). Tương tự thế bạn cũng sẽ muốn lọc dữ liệu nhạy cảm khác như thẻ tín dụng.
Yêu cầu chử ký chéo (CSRF)
Rails bảo vệ bạn khỏi CSRF bằng cách thêm một thẻ xác thực trên các biểu mẫu. Bạn sẽ không thể gửi một hành động POST thành công nếu bạn không có mã thông báo. Điều này được thi hành bởi protect_from_forgery with: :exception
đó được thêm vào application_controller.rb
theo mặc định.
Bạn không thể bỏ qua điều này trên hành động của bạn ngay cả đối với các hành động AJAX. Khi bạn sử dụng đường ray-ujs hoặc jquery_ujs, các thẻ xác thực sẽ được thêm tự động.
Các Strong Parameters
Chắc các bạn không còn xa lạ với keyword Strong Parameter nữa mẫu phổ biến mà chúng ta thường sử dụng là:
Person.create(params[:person])
Điều này có thể sẽ gây ra lỗi Nếu bạn vô tình cập nhật giá trị mà bạn không muốn người dùng cập nhật. Bằng cách sử dụng các Strong Parameters, bạn hãy liệt kê các giá trị có thể được sử dụng như vầy.
params.require(:person).permit(:name, :age)
Bạn đang nói với Rails chỉ name
và age
có thể thay đổi. Nếu người dùng gửi biểu mẫu và ví dụ, được bao gồm admin với giá trị đúng, bạn sẽ gặp lỗi. Không quan trọng là biểu mẫu chỉ có đầu vào cho name
và age
. Một người dùng có thể dễ dàng thay đổi điều đó để thêm nhiều dữ liệu hơn.
Throttling Requests
Trên một số trang như trang đăng nhập, bạn sẽ muốn điều tiết người dùng của mình với một vài yêu cầu mỗi phút. Điều này ngăn không cho chương trình thử nhanh hàng ngàn mật khẩu Rack Attack là một middleware Rack cung cấp sự điều tiết giữa các tính năng khác.
Rack::Attack.throttle('logins/email', :limit => 6, :period => 60.seconds) do |req|
req.params['email'] if req.path == '/login' && req.post?
end
Bảo vệ người dùng của bạn
Trang đăng nhập hoặc trang mật khẩu bị quên sẽ không cung cấp thông tin nếu người dùng có hay không. Sử dụng thông báo chung nếu tên người dùng và mật khẩu sai. Nếu bạn sử dụng một thông báo cho trường hợp khi tên người dùng tồn tại và mật khẩu không đúng và một tin nhắn khác khi tên người dùng không tồn tại thì kẻ tấn công có thể biên dịch danh sách tên người dùng hoặc email của người dùng của bạn.
Sử dụng HTTPS
Sử dụng HTTPS cho toàn bộ trang web của bạn nhưng ít nhất đối với các trang xử lý các thông tin nhạy cảm như trang đăng nhập hoặc thanh toán. Nếu bạn sử dụng HTTP cho trang đăng nhập, bất kỳ ai khai thác mạng của người dùng sẽ thấy mật khẩu trong văn bản rõ ràng.
Chứng chỉ và khóa SSL không được xử lý bởi Rails nhưng trên máy chủ web như nginx, hoặc thậm chí ở trên nó trên bộ cân bằng tải (ví dụ như ELB).
Trên config/environments/production.rb
, bạn có thể chuyển hướng tất cả yêu cầu tới HTTPS.
config.force_ssl = true
không có Credentials trong Repository
Khoá khóa bí mật (secret
key base), chứng chỉ cơ sở dữ liệu và các dữ liệu nhạy cảm khác không được cam kết với Repository
của bạn. Theo mặc định,config / secrets.yml
đọc secret key từ một biến môi trường trong production. Do đó an toàn để thực hiện secrets.yml vào Repository
của bạn.
Nếu database.yml của bạn chứa các chứng chỉ cơ sở dữ liệu của bạn, thì không nên được cam kết vào Repository
của bạn.
Rails 5.1 đã phát hành một mã khóa bí mật tên là encrypt secrets . Nếu bạn đang sử dụng tính năng này, bạn có thể cam kết các tập tin bí mật.
Chứng nhận về biến môi trường(Environment)
Nếu bạn có một sự lựa chọn, không đặt thông tin về các biến môi trường. Nếu bạn cần sử dụng các biến môi trường cho các thông tin quan trọng của mình, đảm bảo rằng các biến môi trường này không bị rò rỉ cho các dịch vụ của bên thứ ba thấy được, ví dụ như để báo lỗi, thường ghi tất cả các biến môi trường trong ứng dụng Rails.
Rails Thông báo Bảo mật
Khi một vấn đề bảo mật Rails được xác định và được vá, bạn sẽ nghe về nó trên danh sách Ở Đây này . Nếu bạn bị ảnh hưởng bởi một vấn đề bảo mật, bạn nên vá ứng dụng Rails của bạn hoặc nâng cấp lên phiên bản mới nhất ngay lập tức.
Chạy Brakeman
Brakeman là một máy quét an ninh phân tích tĩnh cho các ứng dụng Rails. Trong khi bundler-audit
chỉ kiểm tra Gemfile.lock thì brakeman kiểm tra toàn bộ mã của bạn.
Tôi chạy Brakeman trên một trong số ứng dụng Rails cũ của tôi và cho thấy những vấn đề có thể xảy ra với Cross Site Scripting, Denial of Service, Mass Assignment và SQL Injection.
Trang quản trị
Một số ứng dụng cung cấp quyền quản trị cho người có quyền cao hơn để quản lý dữ liệu. Hãy cân nhắc đưa điều này vào một tên miền khác như admin.example.com. Nếu bảng điều khiển dành cho quản trị viên tách biệt khỏi ứng dụng chính, bạn có thể áp dụng nhiều hạn chế hơn như lọc dựa trên IP hoặc chỉ yêu cầu kết nối thông qua VPN của bạn.
SQL Injection
Một số phương pháp ActiveRecord không rà soát được đối số vì vậy bạn phải cẩn thận khi sử dụng chúng với dữ liệu đầu vào của người dùng. Mã ActiveRecord chúng ta thường hay sử dụng phổ biến
User.where(email: params[:email])
Đây là cách phổ biến. Bây giờ hãy xem đoạn mã dưới đây mà bạn có thể nghĩ là tương đương!.
e = params[:email]
User.where("email = '#{e}'")
where
chấp nhận một Chuỗi mà nó chuyển tới WHERE
mệnh đề của truy vấn SQL. 2 phiên bản ở trên trông giống nhau nhưng nếu e được đặt thành "') OR 1-- ", truy vấn sẽ trở thành
SELECT
users.* FROM
usersWHERE (email = '') OR 1-- ')
Bất cứ điều gì sau đó --là một comment
. OR 1sẽ chọn tất cả các bản ghi từ bảng user
Stick với phiên bản đầu tiên như ở trên sử dụng một hash. Chúng ta có thể sử dụng như một mảng như sau:
e = params[:email]
User.where("email = ?", e)
Input của User
Rails theo mặc định sẽ escapes
các giá trị trên các mẫu vì vậy đây không phải là vấn đề nữa.
Khi bạn nhận dữ liệu từ người dùng của mình nhưcomment, sanitize dữ liệu khi hiển thị chúng. Họ có thể nhập html có thể thay đổi thiết kế của trang hoặc tệ hơn có được dữ liệu thông qua Cross Site Scripting (XSS).
All rights reserved