PHP check http referer for form submitted by AJAX, secure?
This is the first time I am working for a front-end project that requires server-side authentication for AJAX requests. I've encountered problems like I cannot make a call of session_start
as the beginning line of the "destination page", cuz that would get me a PHP Warning :
Warning: session_start() [function.session-start]:
Cannot send session cache limiter -
headers already sent (output started at C:\xampp\htdocs\comic\app\ajaxInsert
Book.php:1)
in C:\xampp\htdocs\comic\app\common.php on line 10
I reckon this means I have to figure out a way other than checking PHP session variables to authenticate the "caller" of this PHP script, and this is my approach :
I have a "protected" PHP page, which must be used as the "container" of my javascript that posts the form through jQuery $.ajax();
method
In my "receiver" PHP script, what I've got is:
<?php
define(BOOKS_TABLE, "books");
define(APPROOT, "/comic/");
define(CORRECT_REFERER, "/protected/staff开发者_如何学JAVA/addBook.php");
function isRefererCorrect()
{
// the following line evaluates the relative path for the referer uri,
// Say, $_SERVER['HTTP_REFERER'] returns "http://localhost/comic/protected/staff/addBook.php"
// Then the part we concern is just this "/protected/staff/addBook.php"
$referer = substr($_SERVER['HTTP_REFERER'], 6 + strrpos($_SERVER['HTTP_REFERER'], APPROOT));
return (strnatcmp(CORRECT_REFERER, $referer) == 0) ? true : false;
}
//http://stackoverflow.com/questions/267546/correct-http-header-for-json-file
header('Content-type: application/json charset=UTF-8');
header('Cache-Control: no-cache, must-revalidate');
echo json_encode(array
(
"feedback"=>"ok",
"info"=>isRefererCorrect()
));
?>
My code works, but I wonder is there any security risks in this approach? Can someone manipulate the post request so that he can pretend that the caller javascript is from the "protected" page?
UPDATE:
just realized I can let javascript from the secured page generate a unique token per ajax request, and use the passed token value to authenticate whether it is a "genuine ajax call" from the secured page
Will this be much better? Or should I just encrypt the content of the post request?
UPDATE AGAIN :
After two hours of looping through the included pages, I finally noticed that this weird situation was caused by my PHP page encoding...
I gave Notepad++ a try and carelessly chose the page encoding as UTF-8 with Byte Order Marker, so I kept getting the warning message due to the "weird" interpretation of this line:
<?php
A good lesson for me...
Many thanks to any hints or suggestions.
Technically seen, somebody can send you a request with referrer being 127.0.0.1, 0.0.0.0 or pretty much whatever they want without ever touching the site; so yeah, relying on it might not be the best approach.
Also: You CAN and SHOULD use php_session - you simply have to call session_start(); BEFORE anything else sends ANYTHING (as the error clearly states: headers already sent). Judging from the error
(output started at C:\xampp\htdocs\comic\app\ajaxInsert Book.php:1)
this might simply be a newline at the beginning of the file i.e
//empty line
<?php
//code
Ad. Update: It'll probably make things more secure; given the page which creates the token can only be accessed by people with the required permissions; it seems ok. Though even after reading your comment I believe you have some unneccessary whitespace somewhere, as sessions seem a perfectly fine way to authenticate the AJAX request.
精彩评论