I wanted to get an opinion on how secure my current website is at the moment; I just realized that I had a hole in how I processed content for my site, so I want to make sure I don't have any other problems.
My site works as follows: there is only one actual "file" (the template for the page) that is requested.
Using AJAX, content is loaded into the body of the page each time a link is clicked (so the footer and header always stay in place).
The content for each of these pages are stored in JSON within a similar data structure as my website (i.e. example.com/about's content would be stored in example.com/json/about/data.json). I use JSON because not only is the html for the body of the page stored, but also some custom CSS (which will be injected into the header), the title of the page, and some other attributes are stored as well.
When getting the body content from the server, a connector script (example.com/getcontent.php) is used to retrieve the appropriate content for a page. This connector script is used because within the JSON body content, there is PHP code for pages that require it. The connector script evals the content and then sends the output to the browser.
The security hole I found was that anyone could just go to example.com/json/page/data.json and read all of the PHP code I wrote within the body for each page. I plan to fix this by using mcrypt to encrypt the JSON after creating it, and again using mcrypt within get.php to decrypt it.
Since this is such a big security vulnerability, in my opinion, I was wondering if anyone else could think of something similar that could be wrong with my setup.
NOTE: Only I have access to the server (thus, only I can create the JSON that is evaled), so content that shouldn't be evaled isn't a problem because I am the one that writes the content for each page.
Keep your JSON data outside the web root and make sure that your getcontent.php only serves data from exactly that directory.
So if your web root is /home/website/htdocs, store the json in /home/website/data for example.
In that getcontent.php, make sure that you strip out all .. from the input or use realpath like this:
define(APP_ROOT, '/home/website');
$p = realpath(APP_ROOT.'/data/'.$_SERVER['PATH_INFO']);
if (!preg_match('#^'.realpath(APP_ROOT).'#', $p)){
header('HTTP/1.0 403 Forbidden');
die("Access denied");
}
then you can reference any file in that data folder by a URL in the form of getfile.php/path/to/the/json-file.json
I've deleted my previous answer as I'd misunderstood what you were saying. (and the question really isn't very clear, so it's possible I'm still not getting it)
I still say that any usage of eval()
on the server is a security risk. No matter how tightly you think you've controlled it, if your PHP code contains an eval()
call, there is a very good chance that it's wide open to being hacked.
Don't take that risk: don't use eval()
in PHP. Ever†.
In addition, using eval()
means that PHP can't pre-compile the code, so it'll run much slower than normal PHP code.
You can get away with using eval()
in client-side Javascript because (a) it's the only way to parse JSON in some browsers, and (b) the client can run any Javascript code he likes anyway using Firebug or similar tools. (It'll still be slow, though, so you should still avoid it where possible).
† [edit] To appease @symcbean, I should clarify that you should never use eval()
except in the few occasions where it is the best solution to the problem at hand, and only once you have a firm understanding of the risks involved with using it. These situations are few and far between, however: I've seen eval()
used a lot, but I've never come across code using it properly; it's always been bad code.
精彩评论