2008-10-09 68 views
16

Làm cách nào để ngăn người dùng của tôi truy cập trực tiếp các trang chỉ dành cho cuộc gọi ajax?Ngăn chặn truy cập trực tiếp vào trang PHP

Truyền phím trong khi gọi ajax có vẻ như một giải pháp, trong khi truy cập không có khóa sẽ không được xử lý. Nhưng nó cũng dễ dàng để chế tạo chìa khóa, không? Lời nguyền của nguồn chế độ xem ...

p/s: Sử dụng Apache làm máy chủ web.

EDIT: Để trả lời lý do tại sao, tôi có các tab jQuery ui trong index.php của tôi và bên trong các tab đó là biểu mẫu có tập lệnh, sẽ không hoạt động nếu chúng được truy cập trực tiếp. Tại sao một người dùng muốn làm điều đó, tôi không biết, tôi chỉ hình dung rằng tôi sẽ thân thiện hơn với người dùng bằng cách ngăn chặn truy cập trực tiếp vào biểu mẫu mà không có tập lệnh xác thực.

+2

Đừng lo lắng về sự thân thiện của người dùng trong trường hợp này. Trong thực tế, tôi muốn nói rằng bạn tốt hơn để thất bại sớm hơn là cố gắng làm cho nó dễ chịu. Ví dụ: giả sử bạn chuyển hướng đến index.php cho các lượt truy cập không phải AJAX. Kết quả: ai đó được bảo đảm để đánh dấu các tập lệnh AJAX kể từ khi nó được chúng vào trang chủ của bạn. –

+0

Cookie cũng có thể được giả mạo – AlBeebe

Trả lời

21

Như những người khác đã nói, yêu cầu Ajax có thể được mô phỏng là tạo các tiêu đề thích hợp. Nếu bạn muốn có một tấm séc cơ bản để xem nếu yêu cầu là một yêu cầu Ajax bạn có thể sử dụng:

if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') { 
    //Request identified as ajax request 
} 

Tuy nhiên bạn không nên căn cứ an ninh của bạn trên việc kiểm tra này. Nó sẽ loại bỏ quyền truy cập trực tiếp vào trang nếu đó là những gì bạn cần.

+1

Tôi nhận được chỉ mục không xác định: HTTP_X_REQUESTED_WITH. Bạn có nghĩa là tôi phải tự mình gán giá trị đó không? – syaz

+0

Bạn đang sử dụng khung công tác nào cho các yêu cầu Ajax? (Tôi hy vọng bạn không sử dụng giải pháp homebrewed ...) –

+0

Và, thông số đó sẽ CHỈ có sẵn bên trong yêu cầu Ajax. Bạn có thể muốn thêm một isset() kiểm tra nếu bạn không muốn lỗi chỉ mục không xác định –

34

Không có cách nào đảm bảo rằng họ đang truy cập thông qua AJAX. Truy cập trực tiếp và truy cập AJAX đến từ máy khách, vì vậy nó có thể dễ dàng bị giả mạo.

Tại sao bạn muốn thực hiện việc này?

Nếu đó là vì mã PHP không an toàn, hãy làm cho mã PHP an toàn hơn. (Ví dụ: nếu AJAX của bạn chuyển id người dùng tới tệp PHP, hãy viết mã trong tệp PHP để đảm bảo đó là id người dùng chính xác.)

+4

Không có gì có thể nói thêm. Đừng bao giờ, * bao giờ * tin tưởng những gì khách hàng gửi cho bạn. Vì phương thức AJAX có nghĩa là trả lại nội dung cho trình duyệt, hãy đảm bảo trong chương trình phụ trợ chỉ có thể trả lại dữ liệu được ủy quyền. –

+0

Niềm tiếc duy nhất của tôi là tôi có một phiếu bầu để đưa ra câu trả lời này. –

+4

Nỗi tiếc duy nhất của tôi là tôi bị ngứa xương. – scronide

8

Có vẻ như bạn có thể đang làm những việc sai. Một cuộc gọi AJAX giống như một yêu cầu trang tiêu chuẩn, chỉ bằng cách quy ước, phản hồi không nhằm mục đích hiển thị cho người dùng.

Tuy nhiên, vẫn là yêu cầu của khách hàng và vì vậy bạn phải hài lòng khi khách hàng có thể xem phản hồi. Obfuscating truy cập bằng cách sử dụng một "chìa khóa" theo cách này chỉ phục vụ cho những điều phức tạp.

Tôi thực sự nói rằng "lời nguyền" của nguồn xem là một vũ khí nhỏ trong cuộc chiến chống lại an ninh thông qua sự tối tăm.

Vậy lý do bạn muốn làm điều này là gì?

+0

tôi thích "một vũ khí nhỏ trong cuộc chiến chống lại an ninh thông qua sự tối tăm." một phần - tâm trí nếu tôi trích dẫn nó một thời gian? :) –

+0

hehe, đi cho nó. – Draemon

4

Nếu trình duyệt sẽ gọi trang của bạn, theo yêu cầu bình thường hoặc ajax, thì ai đó có thể gọi nó theo cách thủ công. Có thực sự không phải là một sự khác biệt được xác định tốt giữa các yêu cầu bình thường và ajax như xa như giao tiếp máy chủ-khách hàng đi.

Trường hợp thông thường là chuyển tiêu đề đến máy chủ cho biết "yêu cầu này đã được thực hiện bởi ajax". Nếu bạn đang sử dụng Prototype, nó sẽ tự động đặt tiêu đề http "X-Requested-With" thành "XMLHttpRequest" và một số tiêu đề khác bao gồm phiên bản nguyên mẫu. (Xem thêm tại http://www.prototypejs.org/api/ajax/options tại "requestHeaders")

Thêm: Trong trường hợp bạn đang sử dụng thư viện AJAX khác, bạn có thể thêm tiêu đề của riêng mình. Điều này rất hữu ích khi biết loại yêu cầu nào ở phía máy chủ và để tránh các trường hợp đơn giản khi một trang ajax được yêu cầu trong trình duyệt. Nó không bảo vệ yêu cầu của bạn từ mọi người bởi vì bạn không thể.

0

Bạn không chắc chắn về điều này, nhưng có thể kiểm tra tiêu đề liên kết giới thiệu? tôi nghĩ rằng nếu một người nào đó tự gõ vào url của bạn, nó sẽ không có một tiêu đề liên kết giới thiệu, trong khi các cuộc gọi AJAX làm (ít nhất là trong bài kiểm tra nhanh chóng tôi vừa làm trên hệ thống của tôi).

Đó là cách kiểm tra không đúng. Liên kết giới thiệu có thể để trống vì nhiều lý do. Bạn đang cố gắng ngăn mọi người sử dụng dịch vụ web của bạn như một dịch vụ công cộng hay gì đó?

Sau khi đọc nhận xét chỉnh sửa của bạn, nếu biểu mẫu sẽ được tải qua cuộc gọi ajax, bạn có thể kiểm tra cửa sổ.vị trí để xem liệu url có phải là url của biểu mẫu ajax của bạn không. nếu đúng, hãy truy cập đúng trang qua document.location

+0

Rất dễ giả mạo tiêu đề liên kết giới thiệu. –

+0

@Alex Phải, đó là một trong những lý do được bao gồm trong câu lệnh "có thể để trống vì nhiều lý do". Bao giờ câu trả lời trên trang này có thể được giả mạo, vì chúng là tất cả các phương thức nhập của khách hàng - dữ liệu mà khách hàng gửi đến máy chủ. Đánh dấu mọi câu trả lời trên trang này là tiêu cực. –

0

Điều này chắc chắn không hữu ích để đảm bảo điều gì đó .. nhưng tôi nghĩ rằng điều này có thể được sử dụng nếu bạn muốn nói một trang php tạo ra toàn bộ trang nếu trang không được ajax yêu cầu nhưng chỉ tạo phần mà bạn cần quay trở lại khi ajax được sử dụng .. Điều này sẽ cho phép bạn làm cho trang web của bạn không thân thiện với ajax vì vậy nếu họ nói rằng họ nhấp vào một liên kết và nó phải tải một hộp nhận xét nhưng họ không có ajax nó vẫn gửi chúng đến trang sau đó được tạo dưới dạng toàn bộ trang hiển thị nhận xét.

1

COOKIES không an toàn ... hãy thử $ _SESSION. Đó là một trong số ít những thứ mà bạn thực sự có thể dựa vào trang chéo không thể giả mạo được. Bởi vì, tất nhiên, về cơ bản nó không bao giờ rời khỏi sự kiểm soát của bạn.

0

Chuyển yêu cầu trực tiếp của bạn qua index.php và yêu cầu ajax của bạn thông qua ajax.php và sau đó không cho phép người dùng duyệt trực tiếp bất kỳ tệp nguồn nào khác - đảm bảo rằng index.php và ajax.php có logic thích hợp để bao gồm mã họ cần.

1

cảm ơn, mặc dù tôi sử dụng

define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); 

if(IS_AJAX) { 
    //Request identified as ajax request 
} 

cheers!

0

Trong tập tin javascript mà các cuộc gọi kịch bản:

var url = "http://website.com/ajax.php?say=hello+world"; 
xmlHttp.open("GET", url, true); 
xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 

sau đó trong file php ajax.php:

if($_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") { 
    header("Location: http://website.com"); 
    die(); 
} 

Geeks vẫn có thể gọi kịch bản ajax.php bằng phương pháp rèn header nhưng phần còn lại của tập lệnh của tôi yêu cầu phiên để việc thực hiện kết thúc khi không phát hiện phiên hợp lệ nào. Tôi cần điều này để làm việc để chuyển hướng những người có phiên truy cập hybridauth đã hết hạn đến trang web chính để đăng nhập lại vì họ đã được chuyển hướng đến tập lệnh ajax.

Các vấn đề liên quan