2012-06-06 47 views
3

首先,我很確定類似的問題將在堆棧溢出,但我沒有真正找到它。可能是因爲我使用了錯誤的關鍵字。所以不要因爲這個而開槍。保護PHP包括(使用htaccess?)

我的問題基本上是,我想包括PHP文件,但我只希望他們被包括在內,而不是讓人們用他們的瀏覽器打開。他們應該得到一個錯誤。

例如,我有一個包含php文件的包含目錄,其中包含我與數據庫(密碼等危險?)的連接。我希望能夠包含它,但我不希望人們直接訪問該頁面。

用htaccess將包含目錄的密碼解決我的問題?首先,我認爲它不會,因爲如果用戶沒有訪問權限,那麼可能會包含頁面會很奇怪。但它似乎工作,這是怎麼來的?還有其他更好的選擇嗎?網絡開發者通常會做什麼?

我也可以做類似的JavaScript文件?我的猜測是,情況並非如此,但我只是問。 js文件包含對某些頁面的Ajax調用,但如果我可以保護php頁面不被訪問,我想我很高興。

提前:)

+1

只要你安裝了php並且apache配置正確,訪問任何.php的人只會看到你回顯的內容 –

+0

作爲一個提示,你爲什麼擔心人們看到你的PHP文件的內容?即使*如果*他們試圖通過瀏覽器下載它們,他們所得到的只是這些腳本的輸出(即任何你'回聲')。 – RonLugge

+0

如果我不迴應它,他們絕對沒辦法看到php文件的內容?我不是100%肯定的。基本上我更喜歡在白色頁面上面的錯誤,我猜。 – Anonymous

回答

8

我想解釋這些碎片如何協同工作將有助於消除混淆。

請求(來自用戶的Web瀏覽器)。你的web服務器(在這個例子中是Apache)收到這個。首先,它檢查<Location>權限。然後它查看剩下的配置,並最終將請求URI映射到文件系統。現在,最後,它可以檢查<Directory>權限以及.htaccess

如果任何這些權限檢查的失敗(例如,deny from all),Apache的停止處理該請求,並且(在HTTP基本認證的情況下用戶名&密碼或請求)發送回錯誤。

一旦所有權限檢查都通過,Apache將查看該文件,並注意到它的文件爲.php。在您的(或您的Web主機的)Apache配置中的某處,有一個AddHandler指令告訴Apache將此請求傳遞給PHP引擎(可能是mod_php或通過快速cgi)。 (對於大多數文件,它將文件的內容發送到瀏覽器,但腳本文件是特殊的,因爲那個AddHandler。)

現在,PHP讀取您的腳本文件。然後它也直接讀取您的包含文件。這不會通過Apache返回,因此諸如.htaccess之類的內容不適用。這也意味着你的PHP包含不需要需要在你的文檔根目錄下。它們可以位於PHP進程可以訪問的任何地方(基於UNIX權限和PHP配置)。在你的php.ini中設置include_dir可以很容易地把這些放在任何地方。

客戶端JavaScript由用戶的瀏覽器運行。它不是服務器端解釋的(就像PHP一樣)。所以用戶必須能夠訪問它,就像用戶必須能夠訪問你的.html文件一樣。

因此,簡而言之:

  • 你可以把一個.htaccessDeny from all在你的PHP包含目錄。 PHP的include指令不通過Apache,所以它不會在意。理想情況下,您甚至不會將您的PHP包含目錄放在您的文檔根目錄下。
  • 你不能這樣做JavaScript,因爲JavaScript訪問通過Apache(就像.html,.png等訪問一樣)。
+0

我瞭解除了權限部分以外的所有內容。如果他們與htaccess無關(因爲這是下一步),他們從哪裏來?他們如何編輯? (不是我會這樣做,但我很好奇它們在哪裏定義。) – Anonymous

+0

@ gl3nn它們位於主Apache配置中(在/ etc/apache或/ etc/apache2中,通常至少在Linux上)。如果您使用的是共享主機設置,則可以允許您對VHost配置進行一些更改。 – derobert

+0

是否有可能其他人將包含函數的php文件從我的網站包含到他們的php文件中,然後從它調用函數? – Anonymous

1

反正感謝讓.htaccess文件在你的includes目錄

deny from all 

無法爲客戶端腳本來完成,因爲瀏覽器必須能夠訪問它們。你可以做的最好的是obfuscate them

+0

PHP(或許多服務器端腳本)的混淆是完全不需要和毫無意義的。 – PenguinCoder

+0

我認爲混淆部分是關於客戶端腳本的。但不知道。 – Anonymous

+0

第二部分是關於客戶端腳本,因爲這是OP問題的一部分。爲什麼我會陷入低谷? – ddlshack

2

理想情況下,您的PHP包含應該位於不能直接訪問的文件夾中。

例如:假設您的網站位於/var/www/htdocs/,那麼您應該將index.php放在那裏,但是包含文件應位於網絡可訪問區域之外的單獨文件夾中。在這個例子中,你可以在htdocs旁邊有一個名爲/var/www/includes/的文件夾,其中的PHP包含在內。

這樣,他們完全免受不必要的直接網絡訪問。

另外,您應該編寫您的PHP代碼,使得包含文件僅包含類或函數。這意味着如果通過網絡以某種方式訪問​​它,什麼都不會發生:PHP將加載所有函數,但不會運行它們中的任何一個,因此用戶只會看到一個空白頁面。

如果另一個頁面想要包含該文件,它將需要包含,然後也調用其中的函數;你不應該有一個立即運行代碼的包含。

您應該只編寫在直接用戶訪問的頁面上立即運行的PHP代碼,例如index.php

希望有所幫助。

+0

如果我把文件放在根目錄下,是否真的有必要讓我的所有包含的函數呢?對我的下一個項目來說似乎很聰明,但現在編輯所有內容看起來像是一項長期工作爲你+1。 – Anonymous

+0

@ gl3nn - 是的,將文件移出網絡可訪問區域將在這方面保護它們。在所描述的函數中編寫代碼通常是很好的編程實踐,但是如果你已經寫好了東西,只要把它們放在安全的位置就足夠了。 – Spudley

1

你可以選擇不使用.htaccess(不是說它是一個更好的解決方案,只是一個不同的)。

在你希望用戶直接訪問文件,把下面的之前的任何包括:

@define('IN_APPLICATION', true); 
require 'file.class.php'; //sample include 

然後在包括(類文件),把下面的代碼位於首位:

if (!defined('IN_APPLICATION')){ 
    die(header('HTTP/1.0 404 Not Found')); //or just die(); 
} 

這將確保類文件只有在定義爲IN_APPLICATION的文件(前端)包含時纔可以訪問。你可以選擇使用die()自己而不是僞造404來終止類文件。

0

嗯,正如已經提到的,htaccess不會阻止php訪問htpassword安全文件夾。因此,阿帕奇已經被爲了使用它調用的是這是相當安全的安全功能,至少以https恕我直言,如:

header('Location: secret/index.php'); 

當文件夾祕密固定與htaccess的。

的index.php可能是這樣的:

<?php 
$a = $_REQUEST['a'] ; 
if ($a==secret) 
    header('Location: secret/index.php');  
include_once("index_head.php"); 
include_once("index_tail.php"); 
?> 

和祕密/ index.php文件

<?php 
include_once("../index_head.php"); 
include_once("./secret.php"); 
include_once("../index_tail.php"); 
?> 

剩下的主要問題就是現在,祕密/ index.php文件將無法找到任何聯繫像./main.css等。因此,鏈接必須被定義爲絕對不是相對的,但我相信你們現在該怎麼做;-)

運行示例是http://promotio.ch/secret.php/