5 lỗi bảo mật cơ bản trong Rails app hay gặp trong thực tế
1. Thiếu thời gian hết hạn của session
Như trong Securing Rails Applications ta biết session hay còn gọi là phiên làm việc:
1
2
3
|
Sessions that never expire extend the time - frame for attacks such as cross - site request forgery ( CSRF ) , session hijacking and session fixation . < code class = "language-ruby" >
|
tạm dịch là
1
2
3
|
Sessions sẽ khô ng bao giờ hế t hạ n sẽ là m tă ng thờ i gian cho cá c cuộ c tấ n cô ng như CSRF , session hijacking và session fixation
|
Mặc dù, một phiên không hết hạn dường như phù hợp với quan điểm của người dùng (bởi vì người dùng sẽ ở trong trạng thái được đăng nhập mãi, và sẽ không cần phải đăng nhập lại mỗi khi mở lại ứng dụng), nhưng đó là một quan điểm rất tồi tệ. Điều đó sẽ dẫn tới nguy cơ có ai đó sẽ lấy trộm session của user đấy, bởi vì có một trường hợp nào đó, user đã quên đăng xuất khởi máy tính ở một nơi công cộng như 1 quán net chẳng hạn, do đó, session nên cài đặt thời gian hết hạn.
Giải pháp
Cách đơn giản nhất là cài đặt thời gian hết hạn cho session trong initializer của
1
2
3
|
config / initializers / session_store . rb
|
1
2
3
|
Rails . application . config . session_store : cookie_store , expire_after : 12.hours
|
Với config trên, session cookie sẽ tự động hết hạn trong 12 giờ sau khi tạo. Tuy nhiên, phương pháp này có một lỗ hổng, đó là thời gian hết hạn được cài đặt ở browser của user. Khi đó, nếu có ai đó chiếm quyền kiểm soát session cookie thì có thể dễ dàng tăng thời gian hết hạn bằng cách chỉnh sửa cookie.
Để giải quyết vấn đề trên, thời gian hết hạn nên được lưu lại trên server.
Nếu bạn dùng gem devise cho xác thực user, thì trong gem đó đã xây dựng module Timeoutable dùng cho xác định một phiên làm việc của user đã được hết hạn hay chưa. Để sử dụng nó, bạn cần phải include trong một model user:
1
2
3
4
5
|
class User < ActiveRecord :: Base
devise : timeoutable
end
|
Sau đó, bạn có thể cài đặt option timeout_in
trong initializer của gem devise, mặc định là 30 phút
1
2
3
4
5
6
7
|
# ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity.
# After this time the user will be asked for credentials again.
# Default is 30 minutes.
config . timeout_in = 30.minutes
|
Một cách khác là nếu bạn không thích dùng gem, bạn có thể tạo model Session để lưu lại session của user với thời gian created_at và updated_at, khi sử dụng, chúng ta sẽ loại bỏ các record đã hết hạn.
2. Thiếu cơ chế khoá hệ thống
Một user có thể cố gắng đăng nhập vào hệ thống bao nhiêu lần trước khi bị chặn? Nếu hệ thống của bạn là không giới hạn, điều đó nghĩa là bạn có một lỗ hổng bảo mật lớn. Nếu một user có thể cố gắng kết hợp nhiều email và password mà không có một sự ngăn chặn gì, nghĩa là một cuộc tấn công có thể xảy ra. Có thể là một cuộc tấn công brute-force hoặc dictionary
1
2
3
4
|
Tấ n cô ng Brute - force là cố gắ ng thử kế t hợ p tấ t cả cá c khả nă ng có thể .
Tấ n cô ng Dictionary là cuộ c tấ n cô ng gợ i ý dự a và o mộ t tậ p danh sá ch cá c gợ i ý phổ biế n , gầ n nhấ t vớ i mậ t khẩ u củ a user .
|
Giải pháp
Để sửa chữa vấn đề này, user nên bị khoá sau khi cung cấp một tập các kết hợp không đúng các user name hoặc email và mật khẩu trong một số lần cụ thể.
Nếu bạn sử dụng gem devise, giải pháp cũng đơn giản như vấn đề thứ nhất. Có một model Lockable cho phép chặn truy cập đến một user sau khi có một số lần cố gắng truy cập không thành công. Số lần đó có thể được cài đặt bởi hệ thống, nhưng 5 thường là con số phù hợp.
Module cung cấp 2 chiến lược mở khoá:
:time
sẽ mở khoá user tự động sau một khoảng thời gian được cài đặt.:email
sẽ gửi một email tới user khi tài khoản bị khoá, chưa một link để mở lại tài khoản.
Mỗi một cách có ưu nhược điểm riêng, nhưng quyết định là dựa vào bạn, gem devise đã cung cấp cả 2 cách này.
Ngoài ra , nếu bạn không sử dụng gem, bạn có thể thực hiện một giải pháp đơn giản hơn, vd có thể dùng captcha chẳng hạn
3. Liệt kê, gợi ý địa chỉ email
Đó không phải là một vấn đề nghiêm trọng. Bạn thử vào hệ thống của bạn, chuyển đến trang reset password. Điều gì sẽ xảy ra nếu bạn cung cấp một email không liên quan gì đến user của hệ thống?
Hi vọng đó không trả về một lỗi validate của user với một thông báo là địa chỉ email không tồn tại. Bởi vì, đó có thể dẫn đến một cuộc tấn công, nó giúp kẻ tấn công có thể thu thập danh sách email tồn tại trong hệ thống.
Hacker có thể sử dụng một script tạo ra hàng triệu request với tập các địa chỉ email và dựa theo các phản hồi của hệ thống để xác định email nào tồn tại. Tuy nhiên, bạn có thể chặn đứng cách thức tấn công này bằng cách khoá user như ở phương pháp trên.
Giải pháp
Một ứng dụng nên phản hồi giống nhau khi một user cung cấp địa chỉ email cho một user trong hệ thống. Nhờ vậy, kẻ tấn công sẽ không thể thu thập được các địa chỉ email của user.
Nếu bạn sử dụng gem devise, thì có một config gọi là paranoid
với hướng dẫn trong tài liệu là
1
2
3
|
It will change confirmation , password recovery and other workflows to behave the same regardless if the e - mail provided was right or wrong .
|
tạm dịch
1
2
3
|
Nó sẽ thay đổ i xá c nhậ n , khô i phụ c mậ t khẩ u và cá c quy trì nh cô ng việ c khá c để hoạ t độ ng giố ng nhau bấ t kể email đượ c cung cấ p là đú ng hay sai .
|
Hoặc nếu bạn không sử dụng devise, bạn nên điều chỉnh ứng dụng của bạn để trả về giống nhau nếu một user cung cấp địa chỉ email bị sai
4. Vượt quyền, truy cập trái phép vào tài nguyên
Đấy là một lỗi rất cơ bản, không nên có , nhưng cũng dễ xảy ra nếu ta không cẩn thận. Giả sử bạn tạo một API mới, trả về các user trong project dựa theo id
1
2
3
|
GET https : //my-rails-app.com/api/projects/:project_id
|
Khi gửi một ID của project, sẽ trả về danh sách user của project đó. Tuy nhiên, nếu bạn tạo một request cho một project được quản lý bởi user khác.
Bạn có thể quên việc giới hạn trả về các user chỉ cho project của user hiện tại.
Có một câu nói tổng kết lại về bảo mật rất hay trong tài liệu Rails:
1
2
3
|
As a rule of thumb , no user input data is secure , until proven otherwise , and every parameter from the user is potentially manipulated . < code class = "language-ruby" > < / code > < code class = "language-ruby" >
|
tạm dịch
1
2
3
4
|
< span class = "token constant" > Theo < / span > nguyê n tắ c chung < span class = "token punctuation" > , < / span > khô ng có dữ liệ u đầ u và o củ a ngườ i dù ng là an toà n < span class = "token punctuation" > , < / span > cho đế n khi đượ c chứ ng minh và mọ i thô ng số từ ngườ i dù ng đề u có khả nă ng bị sử a đổ i < span class = "token punctuation" > . < / span >
|
Giải pháp
Luôn luôn ghi nhớ việc giới hạn truy cập tài nguyên vừa đủ nhất có thể. Nếu bạn có thể sử dụng hàm current_user
, thì ta có thể sửa thành:
1
2
3
4
5
6
7
|
# Ban đầu
Project . find ( params [ : id ] )
# Chuyển thành
current_user . projects . find ( params [ : id ] )
|
Nếu bạn muốn kiểm soát các tài nguyên theo phương pháp hướng đối tượng, bạn có thể sử dụng gem pundit
hoặc cancan
Khi đó, mọi action trong controller nên được authorize trước đấy
1
2
3
|
after_action : verify _authorized
|
Gem sẽ thông báo khi bạn quên không gọi hàm authorize
trong action của controller.
5. Cho phép người dùng sử dụng mật khẩu yếu
Đa số các user của hệ thống không sử dụng các công như như 1password hay KeePass để tự động tạo các mật khẩu bảo mật, lưu trữ lại và tự động điền mỗi khi user đăng nhập.
Mà hầu như user lựa chọn các mật khẩu dễ nhớ và thường sử dụng các mật khẩu giống nhau cho mọi ứng dụng.
Tuy nhiên, với trách nhiệm của một người xây dựng hệ thống, thì cần phải thông báo cho user và chịu trách nhiệm về độ bảo mật dù cho điều đó làm cho user không hài lòng.
Chúng ta không nên cho phép tạo các tài khoản với các mật khẩu dễ nhớ như 12345678
hoặc qwerty
. Điều đó rất dễ bị lộ thông tin khi bị tấn công brute-force hoặc dictionary.
Giải pháp
Sử dụng một chính sách khi tạo mật khẩu.
Một chính sách mật khẩu bao gồm tập các quy định được thiết kế để tăng cường độ bảo mật của máy tính bằng cách khuyến khích user sử dụng mật khẩu khó.
Để làm được như vậy, ta chỉ cần thêm một ràng buộc trong model User:
1
2
3
4
5
6
7
8
9
|
validate : password_complexity
def password_complexity
return if password . blank ? || password = ~ / ^ ( ? = . * ? [ A - Z ] ) ( ? = . * ? [ a - z ] ) ( ? = . * ? [ 0 - 9 ] ) ( ? = . * ? [ #?!@$%^&*-]).{8,70}$/
errors . add : password , "Complexity requirement not met. Length
should be 8-70 characters and include: 1 uppercase, 1 lowercase,
1 digit and 1 special character"
end
|
Nếu bạn muốn chắc chắn hơn thì có thể sử dụng gem strong_password
Trên đây là một vài lỗi bảo mật cơ bản của hệ thống, hi vọng sẽ giúp ích được các bạn trong quá trình xây dựng hệ thống chắc chắn cho người dùng.
- 6 Tip để trở thành lập trình viên giỏi
- Lập trình Cặp: chúng ta giúp nhau thành công?
- Tự tạo plugin jQuery, tại sao không?
- Các hoạt động hỗ trợ doanh nghiệp đổi mới sáng tạo. Cách đăng ký nhận hỗ trợ từ Quỹ Phát triển khoa học và công nghệ Quốc gia
- Mật khẩu mặc định của các camera an ninh thông dụng trên thị trường
- Coder 10 tuổi thu hút sự chú ý của Google và Microsoft
- Ba điều rút ra từ Rio Olympics 2016 dành cho các Mobile Marketers
- Apple phát hành iOS 5.1.1, sửa nhiều lỗi quan trọng
- Tất cả về Email Marketing 2.0
- Chia sẻ ứng dụng cài trên thiết bị Android của mình với thiết bị Android khác
- Mẹo giúp tăng tốc dế Android chỉ trong nháy mắt
- Người thông minh thường bừa bộn, thức khuya và chửi thề nhiều! [Nghiên cứu]
DVMS chuyên:
- Tư vấn, xây dựng, chuyển giao công nghệ Blockchain, mạng xã hội,...
- Tư vấn ứng dụng cho smartphone và máy tính bảng, tư vấn ứng dụng vận tải thông minh, thực tế ảo, game mobile,...
- Tư vấn các hệ thống theo mô hình kinh tế chia sẻ như Uber, Grab, ứng dụng giúp việc,...
- Xây dựng các giải pháp quản lý vận tải, quản lý xe công vụ, quản lý xe doanh nghiệp, phần mềm và ứng dụng logistics, kho vận, vé xe điện tử,...
- Tư vấn và xây dựng mạng xã hội, tư vấn giải pháp CNTT cho doanh nghiệp, startup,...
Vì sao chọn DVMS?
- DVMS nắm vững nhiều công nghệ phần mềm, mạng và viễn thông. Như Payment gateway, SMS gateway, GIS, VOIP, iOS, Android, Blackberry, Windows Phone, cloud computing,…
- DVMS có kinh nghiệm triển khai các hệ thống trên các nền tảng điện toán đám mây nổi tiếng như Google, Amazon, Microsoft,…
- DVMS có kinh nghiệm thực tế tư vấn, xây dựng, triển khai, chuyển giao, gia công các giải pháp phần mềm cho khách hàng Việt Nam, USA, Singapore, Germany, France, các tập đoàn của nước ngoài tại Việt Nam,…
Quý khách xem Hồ sơ năng lực của DVMS tại đây >>
Quý khách gửi yêu cầu tư vấn và báo giá tại đây >>