Có lý do nào để không chuyển trực tiếp từ Javascript phía máy khách sang cơ sở dữ liệu không?


62

Có thể trùng lặp:
Viết máy chủ Web Web ứng dụng ít hơn

Vì vậy, giả sử tôi sẽ xây dựng một bản sao Stack Exchange và tôi quyết định sử dụng một cái gì đó như CouchDB làm cửa hàng phụ trợ của mình. Nếu tôi sử dụng xác thực tích hợp và ủy quyền cấp cơ sở dữ liệu, có lý do gì để không cho phép Javascript phía máy khách ghi trực tiếp vào máy chủ CouchDB có sẵn công khai không? Vì về cơ bản, đây là một ứng dụng CRUD và logic nghiệp vụ bao gồm "Chỉ có tác giả mới có thể chỉnh sửa bài đăng của họ" Tôi không thấy cần phải có một lớp giữa nội dung phía máy khách và cơ sở dữ liệu. Tôi chỉ đơn giản là sử dụng xác thực ở phía CouchDB để đảm bảo ai đó không đưa dữ liệu rác vào và đảm bảo rằng các quyền được đặt đúng để người dùng chỉ có thể đọc dữ liệu _user của riêng họ. Việc kết xuất sẽ được thực hiện phía máy khách bằng một cái gì đó như AngularJS. Về bản chất, bạn chỉ cần có một máy chủ CouchDB và một loạt các trang "tĩnh" và bạn sẽ ổn. Bạn sẽ không cần bất kỳ loại xử lý phía máy chủ nào, chỉ cần thứ gì đó có thể phục vụ các trang HTML.

Mở cơ sở dữ liệu của tôi ra thế giới có vẻ sai, nhưng trong kịch bản này, tôi không thể nghĩ tại sao miễn là quyền được đặt đúng. Nó đi ngược lại bản năng của tôi là một nhà phát triển web, nhưng tôi không thể nghĩ ra một lý do chính đáng. Vì vậy, tại sao đây là một ý tưởng tồi?

EDIT: Có vẻ như có một cuộc thảo luận tương tự ở đây: Viết các ứng dụng "máy chủ ít hơn"

EDIT: Thảo luận tuyệt vời cho đến nay, và tôi đánh giá cao phản hồi của mọi người! Tôi cảm thấy mình nên thêm một vài giả định chung chung thay vì gọi CouchDB và AngularJS một cách cụ thể. Vì vậy, hãy giả sử rằng:

  • Cơ sở dữ liệu có thể xác thực người dùng trực tiếp từ cửa hàng ẩn của nó
  • Tất cả các giao tiếp cơ sở dữ liệu sẽ xảy ra qua SSL
  • Xác thực dữ liệu có thể (nhưng có lẽ không nên?) Được xử lý bởi cơ sở dữ liệu
  • Ủy quyền duy nhất chúng tôi quan tâm ngoài các chức năng quản trị viên là ai đó chỉ được phép chỉnh sửa bài đăng của riêng họ
  • Chúng tôi hoàn toàn ổn với mọi người có thể đọc tất cả dữ liệu (hồ sơ người dùng EXCEPT có thể chứa băm mật khẩu)
  • Chức năng quản trị sẽ bị hạn chế bởi ủy quyền cơ sở dữ liệu
  • Không ai có thể tự thêm vai trò quản trị viên
  • Cơ sở dữ liệu tương đối dễ dàng để mở rộng quy mô
  • Có rất ít hoặc không có logic kinh doanh thực sự; đây là một ứng dụng CRUD cơ bản

Không hoàn toàn chính xác là "phía máy khách đến cơ sở dữ liệu", nhưng bạn đã xem Parse và Firebase chưa? (và cả Thiên thạch ở một mức độ nào đó), tất cả chúng đều có các khái niệm có liên quan và tất cả đều xử lý bảo mật theo những cách sáng tạo. ví dụ: xem cái này: blog.firebase.com/post/38234264120/ Kẻ
Eran Medan

Đúng! Tôi đã nghe nói về Parse trước đây nhưng không phải là Firebase. Rất thú vị, và chắc chắn dọc theo dòng suy nghĩ của tôi.
Chris Smith

Cơ sở dữ liệu của bạn sẽ bảo vệ như thế nào trước SQL tiêm hoặc XSS được gửi từ JavaScript? Khá nhiều thứ được gửi từ máy khách mà bạn phải cho là không an toàn, vậy cơ sở dữ liệu nào bạn có thể sử dụng để lọc dữ liệu để đảm bảo rằng nó hợp lệ và chèn dữ liệu với các câu lệnh đã chuẩn bị?
zuallauz

6
Bỏ qua mọi thứ khác, bạn đang tạo một ứng dụng 2 lớp, kết hợp chặt chẽ giao diện người dùng của bạn với cơ sở dữ liệu. Không thực sự là một ý tưởng tốt trừ khi ứng dụng của bạn là tầm thường.
Andy

12
SSL sẽ không ngăn ai đó chạyDELETE FROM ImportantData;
user253751

Câu trả lời:


48

Làm như bạn đề xuất sẽ tạo ra một khớp nối chặt chẽ (er) giữa ngôn ngữ phía máy khách và cơ sở dữ liệu của bạn.

Điều đó có thể ổn - có ít mã hơn để viết và duy trì, và trên lý thuyết, việc gỡ lỗi có thể / nên nhanh hơn một chút.

Mặt khác, nó làm cho các khía cạnh khác khó khăn hơn. Nếu / khi bạn cần thay đổi một trong những công nghệ đó, bạn sẽ có một thời gian khó khăn hơn vì sự liên kết chặt chẽ giữa chúng.

Bảo vệ bản thân trước các cuộc tấn công sẽ khó khăn hơn một chút. Bạn đang giả định rằng máy khách sẽ luôn đưa ra các yêu cầu được định dạng độc đáo cho cơ sở dữ liệu. Điều đó cho rằng sẽ không có ai hack mã phía máy khách để chèn các câu lệnh độc hại. Nói cách khác, họ sẽ "mượn" các cơ chế xác thực của bạn và thay thế mã máy khách thông thường bằng mã của họ.

Tôi sẽ không đề nghị nó, và nhiều người sẽ kịch liệt nói với bạn là không. Nhưng nó có thể được thực hiện.


Hấp dẫn. Kẻ tấn công có thể mượn cơ chế xác thực của tôi như thế nào? Tôi sẽ không tin tưởng khách hàng để xác thực. Cơ sở dữ liệu chỉ đơn giản là đưa một HTTPS POST đến điểm cuối phiên sẽ băm mật khẩu đã đăng và kiểm tra xem nó có hợp lệ không. Nếu đúng như vậy, thì nó sẽ trả lại cookie phiên sẽ được sử dụng trong các yêu cầu trong tương lai.
Chris Smith

1
Tất cả tôi cần là cookie phiên, phải không? Tôi sử dụng khách hàng của bạn để xác thực và nhận cookie phiên của tôi. Sau đó, tôi ăn cắp cookie phiên với khách hàng của mình và gửi các yêu cầu được định dạng xấu để gây ra sự tàn phá. Hãy nhớ rằng đó là tất cả trên máy của tôi, vì vậy tôi thậm chí không cần một cuộc tấn công MiTM.

7
@ChrisSmith - miễn là bạn cảm thấy bạn đang giải quyết các vấn đề bảo mật thì bạn sẽ xử lý sự phản đối chính đối với những gì bạn đề xuất. Nếu bạn đã xử lý chúng hoặc nghĩ rằng bạn làm thì hãy làm điều đó. Phiên bản đơn giản của câu hỏi của bạn là: Bạn hỏi tại sao mọi người không làm ABC. Câu trả lời chính là bảo mật và khớp nối chặt chẽ. Giải quyết những mối quan tâm và mã đi.

2
Chưa kể bạn không có nơi để lưu trữ dữ liệu được yêu cầu thường xuyên, vì vậy bạn sẽ phải nhấn DB mỗi lần. Chắc chắn, có thể trình điều khiển DB của bạn thực hiện một số bộ nhớ đệm, nhưng nó có thể điều chỉnh như thế nào? Nó sẽ chia sẻ trên các chủ đề?
TMN

1
Tôi không thoải mái khi cho phép truy cập trực tiếp vào cơ sở dữ liệu sql của mình thông qua các câu lệnh sql trực tiếp từ các máy khách web vì bạn không bao giờ biết loại yêu cầu nào họ sẽ thực hiện. Họ sẽ chạy xóa, cập nhật hoặc chèn câu lệnh? Nếu họ làm, họ sẽ cung cấp dữ liệu mà ứng dụng của bạn mong đợi? Sẽ xóa bất ngờ? Thay đổi cơ sở dữ liệu bất ngờ thường sẽ phá vỡ ứng dụng của bạn. Tốt nhất là giảm thiểu các lệnh đi đến cơ sở dữ liệu của bạn để bạn có thể dễ dàng vệ sinh các đầu vào bạn nhận được để ứng dụng của bạn có cơ hội hoạt động tốt hơn.
Nathan Pilling

36

Có lẽ nó không phải là một ý tưởng tuyệt vời. Và lý do đầu tiên và mạnh nhất tôi có thể đưa ra là máy chủ cơ sở dữ liệu không được thiết kế để trở thành máy chủ web công cộng. Ngược lại, sự khôn ngoan thông thường nói rằng bạn nên ẩn cơ sở dữ liệu của mình đằng sau tường lửa.

Nếu bạn cần bằng chứng hỗ trợ, có rất nhiều mối quan tâm - không phải tất cả không thể vượt qua, nhưng có rất nhiều điều để suy nghĩ. Không theo thứ tự cụ thể, đây là một vài:

  • Nó không thể thực hiện vệ sinh truy vấn, bởi vì bạn đang gửi nó các truy vấn trực tiếp.
  • Quyền cơ sở dữ liệu có xu hướng hoạt động khác với quyền máy chủ web và quyền ứng dụng. Các máy chủ web và khung ứng dụng bắt đầu với bạn không có gì, và bạn cần phải tạo và hiển thị rõ ràng các tài nguyên, điểm cuối và hành động riêng lẻ. Cơ sở dữ liệu, mặt khác, yêu cầu bạn cấp các vai trò ở mức cao.
  • Có lẽ nó không được tối ưu hóa tốt để duy trì khối lượng công việc của máy chủ web; bạn không thể hưởng lợi từ việc kết nối.
  • Các máy chủ web phổ biến hơn đã được chia thành rất nhiều . Và họ đã nhận được rất nhiều bản vá bảo mật. DBMS của bạn về cơ bản đã được thiết kế để ẩn đằng sau tường lửa, do đó, nó có thể chưa được kiểm tra bởi thậm chí một phần trăm các mối đe dọa tiềm tàng mà nó sẽ phải đối mặt trên web công cộng.
  • Bạn phải sử dụng ngôn ngữ truy vấn của cơ sở dữ liệu để bảo vệ dữ liệu riêng tư. Tùy thuộc vào DBMS của bạn, điều đó có thể là thách thức.
  • Bạn phải sử dụng ngôn ngữ truy vấn của cơ sở dữ liệu để lọc các tập dữ liệu lớn - điều mà bạn có thể cố gắng thực hiện bằng mọi cách; nhưng một cái gì đó có thể trở thành gánh nặng cho các quy tắc kinh doanh phức tạp hơn.
  • Hạn chế hoặc không hỗ trợ cho các thư viện bên thứ ba.
  • Hỗ trợ cộng đồng rất hạn chế (có khả năng bằng không) cho nhiều vấn đề bạn sẽ gặp phải.

... Và tôi chắc chắn có những mối quan tâm khác. Và tôi chắc chắn có một giải pháp cho hầu hết - nếu không phải tất cả những mối quan tâm này. Nhưng, có một danh sách để giúp bạn bắt đầu!


1
Một số thực phẩm tuyệt vời cho suy nghĩ ở đây. Không phải tất cả các điểm này sẽ được áp dụng trong mọi tình huống và sẽ quan trọng như nhau nhưng thật tuyệt khi có một danh sách điểm đạn ngắn gọn có được các bánh răng. Cảm ơn!
Dav

16

Lý do duy nhất tốt nhất tôi có thể tưởng tượng là: bởi vì phương pháp này không được hỗ trợ hoặc khuyến nghị trực tiếp bởi bất kỳ bên liên quan nào.

Các nhà cung cấp trình duyệt, tiêu chuẩn EcmaScript, nhà phát triển hệ thống cơ sở dữ liệu, công ty thiết bị mạng, kiến ​​trúc sư lưu trữ / cơ sở hạ tầng và chuyên gia bảo mật không tích cực hỗ trợ (hoặc thậm chí có thể xem xét) trường hợp sử dụng được đề xuất của bạn. Đây là một vấn đề, bởi vì phương pháp được đề xuất của bạn yêu cầu tất cả các thực thể này - và hơn thế nữa - hoạt động phù hợp cho ứng dụng của bạn, mặc dù không có hệ thống liên quan nào được thiết kế để hỗ trợ điều này.

Tôi không nói là không thể. Tôi chỉ nói điều này ít giống như "phát minh lại bánh xe" và giống như phát minh lại tương tác máy khách-máy chủ dựa trên trình duyệt.

Tốt nhất, bạn sẽ làm rất nhiều việc để thậm chí khiến các hệ thống hoạt động ở mức cơ bản nhất có thể. Các cơ sở dữ liệu phổ biến hiện đại không phải là RESTful hoặc được xây dựng để hoạt động trên HTTP, vì vậy bạn sẽ xây dựng các trình điều khiển máy khách dựa trên WebSocket (tôi đoán).

Ngay cả khi bạn có được mọi thứ để làm việc về mặt kỹ thuật, bạn sẽ từ bỏ nhiều tính năng mạnh mẽ nhất của kiến ​​trúc hiện đại. Bạn sẽ không có sự bảo vệ chuyên sâu - mọi người đều có thể dễ dàng kết nối trực tiếp với mục tiêu chính của hầu hết các nỗ lực hack trang web. Nhưng kịch bản bạn đề xuất còn nhiều, tệ hơn thế nhiều.

Mô hình đề xuất không chỉ là phơi bày máy chủ - nó phơi bày các chuỗi kết nối hợp lệ. Kẻ tấn công không thể ping máy chủ - chúng có thể chủ động đăng nhập và cung cấp lệnh cho nó. Ngay cả khi bạn có thể giới hạn quyền truy cập dữ liệu, tôi không biết có đủ công cụ trong các hệ thống DBMS để bảo vệ khỏi các tình huống từ chối dịch vụ và ilk của chúng. Khi làm việc trong các phiên bản nâng cao của SQL, như TSQL, việc tạo ra những quả bom hoạt động hiệu quả vô cùng dễ dàng (một số ít tham gia để sản xuất một sản phẩm của Cartesian và bạn sẽ có một CHỌN sẽ chạy mãi mãi, làm việc nặng) . Tôi tưởng tượng bạn cần phải vô hiệu hóa hầu hết các tính năng của SQL, thậm chí loại bỏ các truy vấn CHỌN cơ bản bằng THAM GIA và có lẽ chỉ cho phép gọi các thủ tục được lưu trữ? Tôi thậm chí không biết nếu bạn có thể làm điều đó, tôi chưa bao giờ được yêu cầu thử. Nó không'

Khả năng mở rộng cơ sở dữ liệu cũng có xu hướng là một trong những vấn đề khó khăn nhất khi làm việc ở quy mô lớn, trong khi nhân rộng ra nhiều máy chủ HTTP - đặc biệt là với các trang tĩnh hoặc được lưu trong bộ nhớ cache - là một trong những phần dễ nhất. Đề xuất của bạn làm cho cơ sở dữ liệu thực hiện nhiều công việc hơn bằng cách chịu trách nhiệm về cơ bản 100% hoạt động phía máy chủ. Đó là một kẻ giết người hoàn toàn tự nó. Những gì bạn có được từ việc chuyển công việc lên máy khách mà bạn mất bằng cách chuyển nhiều công việc hơn vào cơ sở dữ liệu.

Cuối cùng, tôi chỉ muốn chỉ ra rằng trung tâm của những gì bạn đề xuất không phải là mới, nhưng thực sự đã quay trở lại hàng thập kỷ. Mô hình này được gọi là mô hình "cơ sở dữ liệu chất béo", về cơ bản đã chuyển hầu hết logic phía máy chủ vào cơ sở dữ liệu như bạn đề xuất. Có nhiều lý do mà mô hình đã xuất hiện trên internet, và có lẽ sẽ có nhiều thông tin để tự mình tìm hiểu thêm về lịch sử đó. Cũng lưu ý rằng ngay cả khi đó, có rất ít sự cân nhắc về việc người dùng hoàn toàn không tin cậy có thể đăng nhập vào hệ thống và chạy các lệnh, vì quyền truy cập vẫn sẽ được kiểm soát để chọn người dùng nội bộ (đã biết) không liên tục tấn công hệ thống.

Thực tế là bạn vẫn sẽ cần một máy chủ HTTP để phục vụ các tệp, vì các hệ thống cơ sở dữ liệu không làm điều đó. Đồng thời, mọi thứ bạn đề xuất có thể thu được bằng cách sử dụng mô hình máy chủ mỏng (chẳng hạn như với Nodejs) để hiển thị giao diện RESTful cho cơ sở dữ liệu của bạn. Điều này phổ biến vì một lý do - nó hoạt động, giữ cơ sở dữ liệu ẩn đằng sau các lớp bảo vệ, cực kỳ có thể mở rộng và cho phép bạn xây dựng cơ sở dữ liệu của mình dày hoặc mỏng như bạn quan tâm.


8

Vì về cơ bản, đây là một ứng dụng CRUD và logic nghiệp vụ bao gồm "Chỉ có tác giả mới có thể chỉnh sửa bài đăng của họ" Tôi không thấy cần phải có một lớp giữa nội dung phía máy khách và cơ sở dữ liệu. Tôi chỉ đơn giản là sử dụng xác thực ở phía CouchDB để đảm bảo ai đó không đưa dữ liệu rác vào và đảm bảo rằng các quyền được đặt đúng để người dùng chỉ có thể đọc dữ liệu _user của riêng họ.

Chà, việc đặt ủy quyền của bạn (mối quan tâm bảo mật) và xác thực logic khỏi Cơ sở dữ liệu sẽ phân tách mối quan tâm trong hệ thống phần mềm của bạn. Do đó, bạn có thể kiểm tra, duy trì, chia tỷ lệ và sử dụng lại các khối mã logic của mình với ít rủi ro hơn trong việc hãm chức năng trong hệ thống.

Cung cấp khả năng cho đầu vào của khách hàng giao tiếp trực tiếp với Cơ sở dữ liệu có tiềm năng rất lớn để làm hỏng dữ liệu .

Điều này cũng có nghĩa là việc tránh / loại bỏ khớp nối chặt chẽ làm cho hệ thống phần mềm của bạn dễ bảo trì và RẮN hơn.


1
Tôi thường đồng ý với điều này, nhưng tôi có thể kiểm tra, duy trì và mở rộng các khối mã trong mã phía máy khách dễ dàng như phía máy chủ. Làm tất cả trong Javascript sẽ không phải là một cái cớ để không sử dụng các mối quan tâm riêng biệt. Tôi chỉ đơn giản là di chuyển xử lý thực tế từ máy chủ đến máy khách. Vì vậy, những gì có lớp ở giữa mua tôi?
Chris Smith

2
Có xác nhận phía máy khách là tốt cho khách hàng, nhưng đặt nó ở phía máy chủ của bạn là quan trọng hơn bao giờ hết. Bởi vì, yêu cầu phía khách hàng của bạn có thể được mô phỏng dễ dàng. Có sự phân tách hợp lý và / hoặc tầng giúp cho tính xã hội và khả năng duy trì.
EL Yusubov

Vì vậy, chơi người ủng hộ của quỷ: Như tôi đã đề cập dưới đây, tôi có thể sử dụng các chức năng xác thực của CouchDB để xác định xem dữ liệu được gửi có hợp lệ hay không. Bất cứ khi nào bạn cố gắng thêm hoặc cập nhật một tài liệu, nó sẽ kiểm tra xem bạn có được phép hay không và nó được định dạng chính xác. Nó đặt nhiều xử lý hơn về phía cơ sở dữ liệu, nhưng nó khá nhẹ và tôi cần xem xét mở rộng phía dữ liệu. Điều này sẽ không giải quyết mối quan tâm?
Chris Smith

Không, tôi không nghĩ vậy. Đặt logic xác thực và ủy quyền của bạn trong DB sẽ là hiệu năng đạt được trên hệ thống của bạn, khi số lượng bản ghi bắt đầu tăng lên và bạn có được nhiều người dùng hơn trên hệ thống của mình.
EL Yusubov

Các công cụ DB có nghĩa là lưu trữ và truy xuất dữ liệu, không phải để thao tác hoặc xác nhận nó. Tất nhiên bạn có thể làm theo cách của bạn, nhưng nó không phải là cách hiệu quả để làm theo.
EL Yusubov

6

Để người dùng tương tác với cơ sở dữ liệu trực tiếp dường như thực sự nguy hiểm đối với tôi.

Cơ chế xác thực của CouchDB có thực sự tinh vi đến mức bạn có thể cô lập quyền truy cập đọc và ghi của người dùng chỉ với dữ liệu được cho là đọc và ghi (chúng ta đang nói về mỗi tài liệu, thậm chí có thể truy cập theo từng tài liệu đặc quyền ở đây)? Điều gì về dữ liệu "chung" được chia sẻ bởi nhiều người dùng? Điều này không tồn tại ở tất cả trong thiết kế ứng dụng của bạn?

Bạn có thực sự muốn người dùng có thể thay đổi dữ liệu của mình theo bất kỳ cách nào không? Những gì về tiêm XSS, ví dụ? Sẽ không tốt hơn nếu có một lớp máy chủ để lọc chúng trước khi chúng vào cơ sở dữ liệu?


1
Bạn đưa ra những điểm tốt, và tôi nghĩ điều tương tự. Tôi đi đến kết luận rằng trong ứng dụng (giả thuyết) này, tôi ổn với bất kỳ ai đọc bất kỳ hồ sơ người dùng EXCEPT nào. Họ chỉ có thể viết vào các tài liệu mà họ đã tạo ban đầu (đó là "logic kinh doanh" duy nhất tôi đã đề cập ở trên). CouchDB dường như có khả năng thực hiện cả hai điều này thông qua cơ sở dữ liệu _users nội bộ và các hàm xác thực.
Chris Smith

6

Bạn đã nhận được một số lý do, nhưng đây là một lý do nữa: chứng minh tương lai. Sớm hay muộn, khi ứng dụng của bạn phát triển, bạn sẽ được cung cấp một số yêu cầu không thể đạt được một cách dễ dàng hoặc an toàn trong JS phía máy khách hoặc như một thủ tục được lưu trữ trong cơ sở dữ liệu của bạn.

Chẳng hạn, bạn được thông báo rằng tất cả các đăng ký mới cần phải có xác minh CAPTCHA để hợp lệ. Điều này sẽ thực sự đủ dễ dàng với hầu hết mọi khung ứng dụng web hiện đại. Chỉ cần đặt lại reCAPTCHA trên biểu mẫu đăng ký, chuyển mã thông báo phản hồi của reCAPTCHA trở lại phần phụ trợ và thêm một vài dòng mã vào phần phụ trợ của bạn để xác minh tính hợp lệ của mã thông báo với API của Google (hoặc tốt hơn là sử dụng thư viện mà người khác đã viết để làm điều đó cho bạn).

Nếu bạn đang sử dụng hệ thống hai lớp và dựa vào cơ sở dữ liệu cho tất cả logic phía máy chủ của mình, bạn sẽ xác minh mã thông báo như thế nào? Có, tôi cho rằng về mặt lý thuyết có thể là tùy thuộc vào DBMS để viết một thủ tục được lưu trữ bằng cách nào đó gọi shell và gọi curl với các đối số thích hợp. Đó cũng gần như chắc chắn là một ý tưởng khủng khiếp: lọc đầu vào và bảo vệ chống lại các lỗ hổng bảo mật sẽ rất khủng khiếp; bạn sẽ gặp rắc rối với việc xử lý lỗi và thời gian chờ; và bạn phải tự phân tích câu trả lời. Chưa kể rằng DBMS không có ý định làm điều này, vì vậy không có lý do gì để nghĩ rằng hiệu suất, tính ổn định, an toàn luồng, v.v ... sẽ không phải là vấn đề. Xem, ví dụ, chủ đề này , trong đó thảo luận về một số vấn đề cho Postgres.

Và đó chỉ là vấn đề xung quanh việc thêm một CAPTCHA đơn giản vào một biểu mẫu. Bạn sẽ làm gì nếu bạn muốn thêm xác minh SMS hoặc công việc nền mà email người dùng không hoạt động để nhắc họ về ứng dụng của bạn hoặc thêm tính năng tải lên tệp để mọi người có thể đặt ảnh hồ sơ? Có lẽ bạn quyết định ứng dụng của bạn nên có một số bài kiểm tra tự động một ngày nào đó? Hoặc bạn muốn theo dõi các thay đổi đối với quy trình của mình trong hệ thống kiểm soát phiên bản? Có rất nhiều thư viện và công cụ cho hầu hết mọi ngôn ngữ hữu ích để xử lý hầu hết các tác vụ này cho bạn, nhưng sẽ có ít thư viện không có sẵn cho DBMS của bạn, bởi vì nó không có nghĩa là để làm điều này.

Cuối cùng, bạn sẽ muốn làm một cái gì đó mà bạn không thể làm một cách hợp lý trực tiếp trong DBMS của mình và sau đó bạn sẽ bị mắc kẹt. Vì bạn sẽ xây dựng toàn bộ ứng dụng của mình trong DBMS, nên bạn sẽ không có cách nào khác ngoài việc lấy máy chủ web và bắt đầu xây dựng lại các phần bằng ngôn ngữ khác, chỉ để thêm một tính năng đơn giản.

Và đó sẽ là một sự xấu hổ thực sự, bởi vì chúng tôi đã có một tên cho nơi bạn đặt logic ứng dụng của bạn và nó được gọi là "mã nguồn ứng dụng của bạn" thay vì "thủ tục lưu trữ cơ sở dữ liệu" vì một lý do.


5

Nếu kiểm tra bảo mật và logic nghiệp vụ của bạn được chứa trong javascript phía máy khách của bạn, chúng có thể bị người dùng độc hại ghi đè. Thay vào đó, bạn có thể tận dụng công nghệ phía máy chủ dựa trên JavaScript (như Node.JS ) để xử lý xác thực, ủy quyền và tương tự.


Xác thực và ủy quyền sẽ được xử lý bởi chính cơ sở dữ liệu, vì vậy tôi sẽ không tin tưởng khách hàng về vấn đề đó. CouchDB có các chức năng xác thực tích hợp sẵn kích hoạt bất cứ khi nào bạn cố cập nhật tài liệu để tôi sẽ sử dụng các chức năng đó để kiểm tra xem những gì đang được gửi có hợp lệ không.
Chris Smith

2

Bất kỳ ràng buộc kinh doanh nào bạn có thể muốn đảm bảo phải được xác thực phía máy chủ. Ngay cả khi bạn kiểm soát quyền truy cập của người dùng, ai đó có thể gửi dữ liệu không hợp lệ.

Theo ví dụ nhân bản stackoverflow của bạn:

  • Làm thế nào bạn có thể chặn các câu hỏi "đóng" trên trang web khỏi bị chỉnh sửa?
  • Làm thế nào bạn sẽ ngăn chặn mọi người xóa bình luận?
  • Làm thế nào bạn sẽ ngăn chặn mọi người giả mạo ngày bình luận?
  • Làm thế nào bạn có thể ngăn chặn mọi người nâng cấp 50 lần cùng một bài?
  • Có lẽ có rất nhiều ví dụ nữa nếu bạn đào thêm một chút nữa.

Bất kỳ ai cũng có thể thao túng mã phía máy khách và vi phạm hoàn toàn tính toàn vẹn dữ liệu (ngay cả khi bị giới hạn ở một số đối tượng nhất định, như bài đăng của riêng họ).


1

Chỉnh sửa trang trong fireorms và tại một số điểm đặt một dòng tương tự như sau:

ExecDbCommand("DROP TABLE Users")

Chạy nó

Biên tập:

Câu hỏi thực tế là về CounchDB vì vậy không có sql để chạy ở đây. Tuy nhiên, ý tưởng là như nhau. Tôi sẽ cho rằng bất kỳ ứng dụng không tầm thường nào đều phụ thuộc vào dữ liệu để tôn trọng một số quy tắc nhất quán được kiểm tra / thi hành bởi mã ứng dụng. Người dùng độc hại có thể sửa đổi mã máy khách để lưu dữ liệu ở dạng vi phạm quy tắc kinh doanh của bạn và có thể gây ra sự tàn phá trong ứng dụng của bạn.

Nếu trang web của bạn coi tất cả các trạng thái dữ liệu có thể là hợp lệ từ góc độ kinh doanh thì bằng mọi cách hãy đi theo lộ trình này nhưng nếu đây không phải là trường hợp (có thể) thì bạn sẽ muốn đảm bảo rằng mọi dữ liệu được lưu trữ đều do bạn tạo ra và theo quy tắc của bạn .


CouchDB sẽ không biết phải làm gì với điều đó, nhưng tôi hiểu ý của bạn. Nếu các quyền được đặt đúng, phản hồi cho điều đó sẽ là một trái phép 401.
Chris Smith

-1, khi bạn đăng mã SQL, rõ ràng bạn thậm chí không biết CouchDB là gì. Ngoài ra, chỉ bằng cách tạo tài khoản quản trị viên trên CouchDB, bạn đã ngăn bất kỳ người dùng nào khác thực hiện các hoạt động nguy hiểm nhất.
Phi

đủ công bằng. tôi đã bỏ qua phần trên CouchDB trong câu hỏi và chỉ đăng ký nó dưới dạng "truy cập lưu trữ dữ liệu từ phía máy khách JS". Tôi sẽ chỉnh sửa phản hồi.
AZ01

1
+1, SQL hay không, quan điểm của anh vẫn giữ. Trình gỡ lỗi JS có thể được sử dụng để thay đổi cách truy cập dữ liệu.
GrandmasterB

1

Câu hỏi cũ, tôi biết, nhưng tôi muốn hòa nhập vì kinh nghiệm của tôi khá khác biệt với các câu trả lời khác.

Tôi đã dành nhiều năm để viết các ứng dụng hợp tác thời gian thực. Cách tiếp cận chung cho các ứng dụng này là sao chép dữ liệu cục bộ và đồng bộ hóa các thay đổi với các đồng nghiệp càng nhanh càng tốt. Tất cả các hoạt động trên dữ liệu là cục bộ, vì vậy tất cả lưu trữ dữ liệu, truy cập dữ liệu, logic nghiệp vụ và giao diện người dùng là các lớp là cục bộ. Phong trào "ngoại tuyến đầu tiên" ( http://offlinefirst.org/ ) đã áp dụng phương pháp này để xây dựng các ứng dụng web ngoại tuyến và có thể có một số tài nguyên có liên quan. Những loại trường hợp sử dụng này không chỉ bắt buộc bạn phải mở lớp truy cập dữ liệu của mình cho khách hàng mà còn lưu trữ dữ liệu! Tôi biết rồi mà. Có vẻ điên rồ, phải không?

Mối quan tâm đối với các ứng dụng ngoại tuyến đầu tiên này tương tự như những gì bạn đã hỏi, chỉ cần xóa một cấp. Nó có vẻ liên quan đến tôi. Cho rằng bạn đang mở quyền truy cập dữ liệu trực tiếp vào máy khách, câu hỏi trở thành, làm thế nào bạn có thể hạn chế ảnh hưởng của người dùng độc hại? Chà, có rất nhiều chiến lược, nhưng chúng không rõ ràng nếu bạn đến từ một nền tảng phát triển truyền thống hơn.

Quan niệm sai lầm đầu tiên là phơi bày cơ sở dữ liệu có nghĩa là phơi bày tất cả dữ liệu. Lấy CouchDB làm ví dụ; cơ sở dữ liệu trong CouchDB rất nhẹ, vì vậy bạn sẽ không có ý nghĩ thứ hai về việc tạo ra hàng trăm ngàn cơ sở dữ liệu riêng biệt trên máy chủ. Người dùng chỉ có thể truy cập cơ sở dữ liệu mà họ được cấp quyền truy cập với tư cách là người đọc hoặc người viết (chứ chưa nói đến các tính năng xác thực và không phải của CouchDB), vì vậy họ chỉ có thể truy cập vào một tập hợp con của dữ liệu.

Quan niệm sai lầm thứ hai là người dùng đang sử dụng dữ liệu là một vấn đề! Nếu người dùng được cung cấp một bản sao của cơ sở dữ liệu thì họ có thể tào lao trên tất cả những gì họ thích mà không ảnh hưởng đến những người dùng khác. Nhưng, bạn nên xác thực các thay đổi của họ trước khi sao chép dữ liệu của họ trở lại cửa hàng "trung tâm". Hãy suy nghĩ về Git - người dùng có thể làm những gì họ thích trong các nhánh, nhánh và kho lưu trữ cục bộ mà không ảnh hưởng đến nhánh chính. Sáp nhập trở lại với chủ bao gồm rất nhiều nghi lễ và không được thực hiện một cách mù quáng.

Tôi hiện đang xây dựng một hệ thống bằng CouchDB, nơi người dùng cần cộng tác trên dữ liệu để xây dựng bộ dữ liệu sau đó được "xuất bản" thông qua quy trình làm việc QA / QC. Sự hợp tác được thực hiện trên một bản sao dữ liệu (chúng tôi gọi đây là cơ sở dữ liệu phân tầng hoặc hoạt động) và sau khi hoàn thành, một người có trách nhiệm thực hiện QA / QC trên dữ liệu và chỉ sau đó nó được sao chép trở lại vào kho lưu trữ chính.

Nhiều lợi ích từ điều này khó đạt được trong các hệ thống khác - như kiểm soát phiên bản, sao chép và cộng tác (hãy cùng làm việc ngoại tuyến!) Cho các ứng dụng CRUD ba tầng truyền thống là cực kỳ khó.

Lời khuyên của tôi - nếu ứng dụng của bạn là "truyền thống" thì hãy làm theo cách truyền thống. Nếu bất kỳ điều nào tôi đã đề cập ở trên (mặc dù còn nhiều điều nữa ...) áp dụng cho bạn thì hãy xem xét các kiến ​​trúc thay thế và sẵn sàng suy nghĩ về sau.


0

Tôi nghĩ rằng, với tất cả các giả định của bạn, việc đi trực tiếp từ máy khách đến cơ sở dữ liệu là khả thi. Tuy nhiên, thật hợp lý khi xem xét các giả định của bạn có hợp lệ hay không và có khả năng vẫn còn như vậy trong tương lai.

Tôi sẽ lo lắng rằng trong tương lai mọi người có thể không đọc được tất cả dữ liệu, và đặc biệt là nó có thể phát triển logic kinh doanh nhiều hơn trong tương lai. Cả hai điều này có nhiều khả năng nếu dự án thành công.

Miễn là bạn để lại cho mình một cách để giải quyết những vấn đề này trong tương lai khi và nếu bạn thực sự cần phải giải quyết chúng, tôi nghĩ rằng thiết kế của bạn sẽ hoạt động. Tôi nghĩ rằng bạn sẽ cần phải hết sức cẩn thận để phân tách các mối quan tâm trong mã JavaScript và một số trong số đó có thể sẽ được viết lại trên máy chủ sau này.

Nhưng tôi chắc chắn có thể thấy nơi nào có thể có giá trị rủi ro có thể làm điều đó sau này so với lợi ích của việc ít bộ phận chuyển động ngày nay.


Điểm tốt. Đây chắc chắn là một trường hợp sử dụng hẹp, vì vậy đây không phải là thứ bạn có thể áp dụng cho bất kỳ ứng dụng nào.
Chris Smith

0

Trước hết cảm ơn về câu hỏi NGOÀI HỘP .... :)

Nhưng những gì tôi muốn đề nghị là; Luôn cố gắng duy trì sự tách biệt giữa 3 lớp của bạn. đó là Bản trình bày / Kinh doanh và Cơ sở dữ liệu hoặc DAO vì đó sẽ là cách thực hành tốt nhất trong các loại yêu cầu và thiết lập đó, nơi sẽ có rất nhiều thay đổi mỗi ngày.

Trong các thế giới đơn giản, lớp Trình bày của bạn không nên biết về lớp Cơ sở dữ liệu, tức là Định dạng của một số trường loại ngày có thể khác với lớp trình bày và lớp cơ sở dữ liệu để người dùng có thể tự do chọn định dạng phù hợp của ngày theo nhu cầu của mình.

Và Business Logic phải hoạt động giống như một khớp nối giữa lớp trình bày và lớp cơ sở dữ liệu / Dao như đúc các trường, một số xác nhận nghiệp vụ, v.v. nên được xử lý trên Lớp nghiệp vụ thay vì trong phần Javascript theo câu hỏi của bạn.

Sự tách biệt này sẽ cung cấp cho bạn sự dễ dàng và ứng xử tuyệt vời trong các tình huống phức tạp, chức năng-es và thậm chí cả các xác nhận phức tạp. Ưu điểm tốt nhất là: bạn có thể có các công nghệ khác nhau để thực hiện các lớp này và có thể được thay đổi theo nhu cầu hoặc phạm vi kinh doanh.

Cảm ơn


0

Nếu bạn muốn xây dựng SQL bằng JavaScript và gửi nó đến cơ sở dữ liệu, xác minh các quyền, v.v., hơn là vì lý do bảo mật thì đó sẽ là một thảm họa. Đơn giản là vì khi bạn xây dựng API và tự xây dựng các truy vấn, bạn phải phân tích theo quan điểm bảo mật chỉ với số lượng truy vấn hạn chế. Nếu các truy vấn được xây dựng bên ngoài hệ thống của bạn, bạn có khả năng không giới hạn số lượng thủ thuật mà ai đó có thể làm.

Nhưng đó không phải là trường hợp vì bạn đang sử dụng cơ sở dữ liệu khóa-giá trị (công bằng như tôi hiểu, CouchDB thường rơi vào danh mục đó). Bản thân giao diện cơ sở dữ liệu là một loại lớp giữa và được nhóm Apache kiểm tra vì lý do bảo mật. Do API JavaScript tương đối đơn giản, điều này thậm chí còn dễ dàng phân tích hơn cho các lỗ hổng tiềm năng so với các giao diện phức tạp như vậy mà các ứng dụng JSF có.

Đây có thể là một giải pháp an toàn, nếu bạn thực hiện các bài kiểm tra bảo mật phức tạp. Điều này thậm chí có thể dễ dàng hơn khi sử dụng các khung công tác như JSF, thường sử dụng API khó đọc phía sau. Bảo mật bằng cách che khuất được coi là không có giải pháp.

Liên quan đến câu hỏi của bạn, dù sao nó cũng sẽ không được truy cập trực tiếp vào cơ sở dữ liệu. Truy cập trực tiếp sẽ là các truy vấn SQL xây dựng trong JavaScript (không may, tôi đã thấy các giải pháp như vậy). Trong trường hợp của bạn, chính CouchDB cung cấp lớp cách ly. Tất nhiên bạn có thể bọc nó trong API của mình để làm cứng nó, nhưng miễn là bạn có thể dễ dàng kiểm tra những gì người dùng cụ thể có thể làm và nếu các ràng buộc bảo mật đang hoạt động cho bạn, bạn sẽ có giải pháp an toàn và mạnh mẽ mà không cần thêm lớp.


0

Tôi thấy hai vấn đề:

1. Khớp nối chặt chẽ: Thay đổi tùy chọn DB của bạn? Chà, bây giờ bạn cũng phải thay đổi tất cả mã phía khách hàng của mình. Tin tôi đi Chúng tôi không cần nhiều vấn đề hơn về phía khách hàng.

2. Vấn đề bảo mật TMI: Tiết lộ quá nhiều về cách thức hoạt động của công cụ. Auth có thể vẫn là một trở ngại nhưng việc tìm kiếm khai thác dễ dàng hơn rất nhiều khi bạn biết chính xác những gì đang xảy ra ở phía máy chủ.

Một tầng lớp trung lưu rất mỏng có thể là một cách tốt hơn để đi.


-1

Khách hàng của bạn không thể sử dụng ứng dụng web của bạn nếu javascript bị vô hiệu hóa (hoặc không được hỗ trợ trên trình duyệt của thiết bị của anh ấy) nếu javascript là lớp truy cập cơ sở dữ liệu duy nhất.


2
Eh, không quá lo lắng về điều này. Hầu hết các web hiện nay đều dựa vào Javascript. Tôi có thể phải thoát ra các thẻ <noscript> và nói với họ rằng họ cần bật nó nếu họ muốn trang web của tôi (và 80% các thẻ khác ngoài đó) hoạt động.
Chris Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.