Hỏi về cách chống phá hoại javascript
Em xin chào mọi người
Em đang nghịch cái asp , chuyện là em có làm các hàm javascript để thực hiện 1 số công việc phục vụ chính cho ajax ( cụ thể là thêm xóa sửa giỏ hàng ) , chuyện không có gì cho tới khi em vô tình xem được 1 bài viết khi nói về js, khi em tạo hàm chạy trên web , người phá hoại hoàn toàn có thể dùng các hàm này để phá rối web , đây là ví dụ điển hình của em ạ :
Đầu tiên em làm thêm xóa sửa gộp vô chung cái hàm , em lấy ví dụ là hàm sửa :
function CatNhapGioHang(maSP, soLuong, tenSP, Loai) {
//Loại == 1 : Sửa
if (Loai == 1) {
$.ajax({
url: '/Cart/SuaGioHang',
type: 'POST',
data: JSON.stringify({ 'MaSP': maSP, 'SoLuong': soLuong }),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data == "true") {
Reload();
}
},
error: function () {
}
});
Em cho web chạy lên và gọi hàm này từ cửa sổ console của trình duyệt :
Và kết quả là em ăn hành sml :
Cho em hỏi những trường hợp thế này em phải giải quyết thế nào ạ?
Em xin chân thành cảm ơn ạ
Bạn phải kiểm tra quyền hạn của user trước khi thực thi function của bạn.
Xem ai được phép xóa sửa, ai thì không.
Bước này gọi là authorization
Nếu có sai sót thì bỏ qua cho em vì em rất giốt tiếng anh, em tìm hiểu thì cũng có 1 số tool hỗ trợ việc này nhưng trên stackoverflow họ cũng cảnh báo dùng cách em tạm hiểu là " Làm rối" này cũng tự làm khó coder , khiến việc debug trở nên khó khăn hơn , việc này có thực sự ảnh hưởng nhiều không ạ ?
Em có Validation đó chứ ạ , nhưng em muốn hỏi thử xem có cách nào kiểu kiểu như giấu luôn cái script không ấy mà . Em cũng có tìm hiểu qua nhưng gần như kết quả trả về là bất khả thi vì trình duyệt sẽ load script về để chạy ( theo em hiểu là vậy )
Em cảm ơn bác nhiều ạ
Nếu người khác gọi được hàm của bạn ở console của trình duyệt, thì có nghĩa là hàm đó có phạm vi toàn cục (global scope).
Vì vậy, để ngăn chặn thì bạn chỉ cần đưa tất cả hàm và biến của bạn khỏi global scope, bằng cách sử dụng IFFE.
Ví dụ như sau:
Không biết câu trả lời này có đúng với ý của bạn không?
dạ em có authorization ạ , cụ thể là ở những chức năng k cần đăng nhập ( như mua hàng ) thì em tạm bỏ qua , còn chức năng nào cần đăng nhập thì em làm như sau :
Nhưng em cảm thấy việc này không hay lắm vì lần nào cũng phải validate với sever cả, em nghĩ mà ví dụ như em test 1, 2 cái request thì không sao nhưng nếu về sau giả vờ có cả hàng ngàn request thì việc này liệu có dẫn tới bị chậm không ạ ?
Trên đây là thắc mắc của em mong được bác giải đáp ạ .
Em xin chân thành cảm ơn
Bạn có giấu thì hay làm rối code khi thực hiện 1 request thì mình vẫn có thể bật tab Network trong chrome và theo dỏi (xhr). Validate vẫn tốt hơn : )
Bạn có thể code mọi thứ chạy xong xuôi, thì mới “làm rối” nên ko ảnh hưởng đến quá trình code đâu.
Cơ mà dù có “làm rối” thì cao thủ cũng gỡ rối đc hết . Tốt nhất validation trên server là đc, ở client thì kệ xác chúng nó, muốn sửa gì thì sửa thôi.
Bác cho em hỏi thêm vì JS em lưu ở 1 file riêng và vì 1 hàm em phải nhai đi nhai lại nhiều lần ở nhiều trang , nếu đưa nó thành cục bộ thì em đâu thể dùng ở nhiều trang phải không ạ ?
Vâng em nghĩ 1 chiều quá , em cảm ơn bác đã chỉ dạy ạ .
vâng ạ , cho em hỏi thêm như vậy em phải validate tới 2 lần cả ở client lẫn sever phải không ạ ?
Tại client em validate để chắc chắn người dùng phổ thông không nhập sai .
Tại sever để cố gắng chống lại “thế lực bóng tối”
em nghĩ vậy có đúng với thực tế không ạ , lúc đầu làm thì em cứ làm theo video hướng dẫn thôi , lúc sau em xem lại thì thấy nhiều thứ phải xem lại quá
Đúng rồi đó bạn, validate ở client để giảm tải request đến server nữa.
Còn ko thì bạn có thể validate ở mỗi server không cũng đc à.
Dạ thôi tại em đang học không phải làm nên cố gắng tý ạ
Em cảm ơn bác nhiều ạ
Kiểm tra auth và validate là bắt buộc rồi, chỉ cần dùng session để lấy thông tin người dùng hiện tại.
Token mã hoá thông tin cilent+auth, lưu vào cookie và database để tự đăng nhập lại khi session hết hạn.
Tất cả quyền truy cập sẽ được lưu vào cache hoặc một file nào đó, gọi là access control lists. Nó phải được cập nhật khi phân quyền bị thay đổi. Khi bạn kiểm tra quyền thêm sửa xoá là bạn kiểm tra session với acl chứ không nên với database.
Bình thường không ai đi đọc script và dùng script của bạn để phá cả, người ta sẽ theo dõi network để lấy request luôn, sau đó lặp lại nó là xong.
Kiểu tấn công này gọi là csrf. Để chống lại nó, trong form data của bạn phải có một field luôn thay đổi mà bạn kiểm tra được.
Có thể tạo ngẫu nhiên một cặp key+value mã hoá mỗi khi tạo form, lưu vào session. Sau đó kiểm tra key với value khi người dùng gửi request.
Nếu dùng ajax thì sau khi kết thúc request, nhớ kèm theo key mới trong response được trả về.
Dạ xin phép bác cho em hỏi thêm 1 chút ạ :
Trước em có tìm hiểu session, cookie và local storage thì em thấy cái nào cũng có cái giở của nó và không cái nào mang tính toàn vẹn , em thắc mắc nếu em lưu phân quyền vô cookie thì nếu nó bị đánh cắp thì rủi ro có phải sẽ cao hơn không ạ . Hiện tại em đang làm theo kiểu để sever gồng gánh , nghĩa là mỗi khi chuyển trang hay làm mới trang thì em đều validate cookie với server, em biết thế là tội cho cái server nhưng với trình độ hiện tại em chưa nghĩ ra được cách nào hơn cả , mong bác chỉ bảo .
Em có nghĩ tới việc dùng google captcha để validate form coi như là một key nhưng em không cài được trên local host để test , em có nghĩ tới việc cho sinh số ngẫu nhiên từ 1000-9999 rồi rùng nó để validate nhưng em vẫn đang tìm hiểu cách hay hơn ạ .
Cuối cùng em xin chân thành cảm ơn bác đã chỉ bảo , em sẽ tìm hiểu và cải thiện ạ.
Không lưu phân quyền vô cookie, chỉ nên sử dụng cookie cho việc đăng nhập lại sau khi session hết hạn.
Không nên dùng captcha để bảo mật form. Đúng là có tác dụng thật, nhưng sẽ gây phiền phức cho người dùng.
Mình sẽ ví dụ cho bạn mẫu mình hay dùng, mẫu này đã được tối giản để bạn dễ theo dõi.
Database
Dùng để chia cấp bậc như Admin, Manager, Member.
Thông tin người dùng.
Lưu token sau khi đăng nhập thành công.
Xác định quyền theo cấp bậc.
Đăng nhập lần đầu
Khi người dùng đăng nhập thành công, bạn lấy
username
+password
+user_agent
(thông tin trình duyệt) và mã hóa chúng để tạotoken
, có thể dùng md5 để mã hóa.Lưu vào cookie
id_user
vàtoken
vừa tạo. Đồng thời cũng ghi vào RememberTokens.Tạo session
auth
chứaid_user
vàid_role
.Phân quyền bằng ACL
ACL có thể lưu trong cache là tốt nhất, nếu không được thì lưu thành file, dù sao vẫn sẽ tốt hơn truy cập vào database.
Khi chưa có ACL thì bạn truy cập Permissions để lấy và tạo ACL chứa toàn bộ dữ liệu của nó. Ví dụ thế này:
Khi người dùng thực hiện thao tác nào đó ta sẽ có được
controller
vàaction
, thêmid_role
trong session nữa là đủ để bạn so sánh với ACL. Nếu không tồn tại trong ACL thì cấm hết.Đăng nhập trở lại bằng cookie
Session hết hạn, và cookie vẫn còn.
Lấy
id_user
từ cookie, kiểm tra tồn tại trong Users và lấy được thông tin người dùng.Dùng
username
vàpassword
vừa lấy, cộng thêmuser_agent
của trình duyệt hiện tại là bạn tạo đượctoken
.Kiểm tra
token
vừa tạo đó với cái đang lưu trong cookie.Có được
token
vàid_user
rồi thì kiểm tra RememberTokens.Khi các thông tin đã đúng thì tạo lại session
auth
.Đăng xuất
Người dùng đăng xuất thì xóa cookie, session và dữ liệu trong RememberTokens.
Chống CSRF
Tạo chuỗi ngẫu nhiên mỗi khi nhập form, đồng thời ghi vào form nhập liệu của người dùng. Ví dụ: abcXYZ
Khi người dùng gửi request thì kiểm tra
token
, đồng thời xóa nó khỏi session.Ví dụ đơn giản để bạn hình dung, chứ thực tế không nên dùng như vậy. Ngoài
token
người ta còn tạo thêm sessiontoken_time
giới hạn thời gian. Còntoken
thì dùng các hàm băm như bcrypt để mã hóa, bạn sẽ có 2 chuỗitoken
khác nhau cho session và form, an toàn hơn.Hiểu nguyên tắc thì có thể viết được, nhưng bạn nên dùng các thư viện đã được nhiều người kiểm chứng. Vừa bảo mật, vừa tránh được vấn đề hiệu suất.
Em cảm ơn bác , bác nhiệt tình quá , em sẽ tham khào và phát triển thêm, cảm ơn bác rất nhiều ạ .
Bạn dùng chứng thực Authentication Header cho ajax. Hoặc dùng anonymous function.