포함으로 독점적으로 사용할 PHP 파일이 있습니다. 따라서 포함되지 않고 URL을 입력하여 직접 액세스 할 때 오류를 실행하는 대신 오류를 발생시키고 싶습니다.
기본적으로 PHP 파일에서 다음과 같이 확인해야합니다.
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
이 작업을 수행하는 쉬운 방법이 있습니까?
포함으로 독점적으로 사용할 PHP 파일이 있습니다. 따라서 포함되지 않고 URL을 입력하여 직접 액세스 할 때 오류를 실행하는 대신 오류를 발생시키고 싶습니다.
기본적으로 PHP 파일에서 다음과 같이 확인해야합니다.
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
이 작업을 수행하는 쉬운 방법이 있습니까?
답변:
일반적인 "완전히 제어 할 수도 있고 아닐 수도있는 Apache 서버에서 실행되는 일반적인 PHP 앱"의 가장 쉬운 방법은 디렉토리에 포함을 넣고 .htaccess 파일에서 해당 디렉토리에 대한 액세스를 거부하는 것입니다. 사람들이 인터넷 검색 문제를 해결하기 위해 Apache를 사용하는 경우 액세스하지 않으려는 디렉토리의 ".htaccess"라는 파일에 파일을 넣으십시오.
Deny from all
실제로 서버를 완전히 제어 할 수 있다면 (이 답변을 처음 쓸 때보 다 작은 앱에서도 더 일반적입니다) 가장 좋은 방법은 웹 서버가 제공하는 디렉토리 외부에서 보호하려는 파일을 고정하는 것입니다 . 따라서 앱이에있는 경우 /srv/YourApp/
서버가 파일을 제공 /srv/YourApp/app/
하고 포함을 넣 도록 설정하십시오 /srv/YourApp/includes
. 따라서 문자 그대로 액세스 할 수있는 URL이 없습니다.
<Files ~ "\.inc$">
Order Allow,Deny
Deny from All
</Files>
포함시키고 자하는 페이지에 추가하십시오
<?php
if(!defined('MyConst')) {
die('Direct access not permitted');
}
?>
그런 다음 포함 된 페이지에서
<?php
define('MyConst', TRUE);
?>
somefile.php
서버에서 작성 하고 정의를 추가 한 경우 여전히 포함 파일에 직접 액세스 할 수 없습니다. 라이브러리 파일을 "포함"할 수는 있지만 서버에서 파일을 작성하고 정의 / 포함 스크립트를 알기에 충분할 경우 정의를 사용하여 자신의 파일을 작성하지 못하게하는 다른 문제가 있습니다. .
포함 된 경우와 직접 액세스 한 경우 (주로 print()
vs return()
) 다르게 행동 해야하는 파일이 있습니다. 다음은 수정 된 코드입니다.
if(count(get_included_files()) ==1) exit("Direct access not permitted.");
액세스되는 파일은 항상 포함 된 파일이므로 == 1입니다.
파일에 직접 액세스하지 못하게하는 가장 좋은 방법은 파일을 웹 서버 문서 루트 외부 (일반적으로 한 수준 위)에 두는 것입니다. 여전히 포함 할 수 있지만 http 요청을 통해 누군가가 액세스 할 가능성은 없습니다.
나는 보통 끝까지 가고 모든 웹 사이트 / 애플리케이션을 라우팅하기 시작하는 문서 루트의 고독한 index.php- 부트 스트랩 파일을 제외하고 모든 PHP 파일을 문서 루트 외부에 배치한다 .
if( count(get_included_files()) == ((version_compare(PHP_VERSION, '5.0.0', '>='))?1:0) )
{
exit('Restricted Access');
}
논리 : 최소 포함 횟수에 맞지 않으면 PHP가 종료됩니다. PHP5 이전에는 기본 페이지가 포함으로 간주되지 않습니다.
// In the base page (directly accessed):
define('_DEFVAR', 1);
// In the include files (where direct access isn't permitted):
defined('_DEFVAR') or exit('Restricted Access');
논리: 상수가 정의되어 있지 않으면 기본 페이지에서 실행이 시작되지 않아 PHP 실행이 중지됩니다.
참고 이 크게 변경 하드 코딩 된 모든 단일 파일에있을 필요하지 않으므로 오버 헤드 코딩 줄일이 인증 방법의 모듈을 업그레이드하고 미래의 변화 이식성을 위해서, 대한.
// Put the code in a separate file instead, say 'checkdefined.php':
defined('_DEFVAR') or exit('Restricted Access');
// Replace the same code in the include files with:
require_once('checkdefined.php');
이러한 방법으로 로깅 및 분석 목적과 적절한 응답 생성 을 위해 추가 코드를 추가 할 수 있습니다 checkdefined.php
.
신용이 필요한 신용 : 이식성에 대한 훌륭한 아이디어는 이 답변 에서 비롯되었습니다 .
// Call the include from the base page(directly accessed):
$includeData = file_get_contents("http://127.0.0.1/component.php?auth=token");
// In the include files (where direct access isn't permitted):
$src = $_SERVER['REMOTE_ADDR']; // Get the source address
$auth = authoriseIP($src); // Authorisation algorithm
if( !$auth ) exit('Restricted Access');
내부 요청과 함께 세션 토큰을 제공하지 않는 한이 방법의 단점은 격리 된 실행입니다. 단일 서버 구성의 경우 루프백 주소 또는 다중 서버 또는로드 밸런스 서버 인프라의 주소 화이트리스트를 통해 확인하십시오.
이전 방법과 마찬가지로 GET 또는 POST를 사용하여 포함 파일에 권한 부여 토큰을 전달할 수 있습니다.
if($key!="serv97602"){header("Location: ".$dart);exit();}
올바른 방법으로 사용하면 매우 지저분한 방법이지만 동시에 가장 안전하고 다목적입니다.
대부분의 서버에서는 개별 파일 또는 디렉토리에 대한 권한을 할당 할 수 있습니다. 모든 포함을 이러한 제한된 디렉토리에 배치하고 서버가이를 거부하도록 구성 할 수 있습니다.
예를 들어 APACHE에서 구성은 .htaccess
파일에 저장 됩니다. 여기 튜토리얼 .
참고 서로 다른 웹 서버에서 휴대 나쁜 때문에 서버 별 구성 날에 의해 권장하지 않습니다 그러나 것을. 거부 알고리즘이 복잡하거나 거부 된 디렉토리 목록이 다소 큰 콘텐츠 관리 시스템과 같은 경우에는 재구성 세션 만 다소 소중하게 만들 수 있습니다. 결국 코드에서 이것을 처리하는 것이 가장 좋습니다.
서버 환경에서의 액세스 제한 때문에 파일 시스템에 대한 액세스 권한이있는 경우 다소 강력한 방법이 가장 선호됩니다.
//Your secure dir path based on server file-system
$secure_dir=dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR;
include($secure_dir."securepage.php");
논리:
htdocs
링크가 웹 사이트 주소 시스템의 범위를 벗어나므로 폴더 .정통 코딩 규칙을 실례하겠습니다. 모든 의견을 부탁드립니다.
실제로 내 조언은 이러한 모범 사례를 모두 수행하는 것입니다.
if (!defined(INCL_FILE_FOO)) {
header('HTTP/1.0 403 Forbidden');
exit;
}
이런 식으로 파일이 잘못 배치 된 경우 (잘못된 FTP 작업) 여전히 보호됩니다.
하나의 진입 점으로 응용 프로그램을 빌드하는 것이 좋습니다. 즉 모든 파일은 index.php에서 도달해야합니다.
이것을 index.php에 넣으십시오.
define(A,true);
이 검사는 링크 된 각 파일에서 실행해야합니다 (필수 또는 포함을 통해).
defined('A') or die(header('HTTP/1.0 403 Forbidden'));
PHP 파일 에 대한 액세스를 직접 제한하고 싶지만을 통해 파일을 호출 할 수도 있습니다 jQuery $.ajax (XMLHttpRequest)
. 여기 나를 위해 일한 것이 있습니다.
if (empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && $_SERVER["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest") {
if (realpath($_SERVER["SCRIPT_FILENAME"]) == __FILE__) { // direct access denied
header("Location: /403");
exit;
}
}
가장 쉬운 방법은 호출에 포함하는 파일에 일부 변수를 설정하는 것입니다.
$including = true;
그런 다음 포함되는 파일에서 변수를 확인하십시오.
if (!$including) exit("direct access not permitted");
.htaccess 방법 외에도 다양한 프레임 워크 (예 : 루비 온 레일)에서 유용한 패턴을 보았습니다. 응용 프로그램 루트 디렉토리에는 별도의 pub / 디렉토리가 있으며 라이브러리 디렉토리는 pub / 와 동일한 레벨의 디렉토리에 있습니다. 이와 같은 것 (이상적이지는 않지만 아이디어를 얻음) :
app/
|
+--pub/
|
+--lib/
|
+--conf/
|
+--models/
|
+--views/
|
+--controllers/
pub /를 문서 루트로 사용하도록 웹 서버를 설정했습니다. 이를 통해 스크립트를보다 효과적으로 보호 할 수 있습니다. 스크립트는 문서 루트에서 접근하여 필요한 구성 요소를로드 할 수 있지만 인터넷에서 구성 요소에 액세스하는 것은 불가능합니다. 보안 외에 다른 이점은 모든 것이 한 곳에 있다는 것입니다.
이 설정은 "access not allowed"메시지가 공격자에게 실마리가되기 때문에 포함 된 모든 단일 파일에서 검사를 만드는 것보다 낫고, 화이트리스트 기반이 아니기 때문에 .htaccess 구성보다 낫습니다. lib /, conf / 등 디렉토리에는 보이지 않습니다.
내 답변은 접근 방식이 다소 다르지만 여기에 제공된 많은 답변이 포함되어 있습니다. 여러 가지 방법을 권장합니다.
defined('_SOMECONSTANT') or die('Hackers! Be gone!');
그러나이defined or die
접근 방식은 실패의 번호가 있습니다. 첫째, 테스트하고 디버깅하는 것은 가정에서 큰 고통입니다. 둘째, 마음이 바뀌면 끔찍하고 정신없이 지루한 리팩토링이 필요합니다. "찾기 및 교체!" 당신은 말합니다. 예, 그러나 그것이 정확히 어디에서나 똑같이 쓰여 졌음을 확신합니까? 이제 수천 개의 파일로 곱하십시오 ... oO
그리고 .htaccess가 있습니다. 관리자가 그렇게 신중하지 않은 사이트에 코드를 배포하면 어떻게됩니까? 파일을 보호하기 위해 .htaccess에만 의존하는 경우 a) 백업, b) 눈물을 말릴 수있는 티슈 상자, c) 사람들로부터 모든 혐오에 화염을내는 소화기 코드를 사용하여.
그래서 질문이 "가장 쉬운"을 요구한다는 것을 알고 있지만, 이것이 요구하는 것은 더 "방어적인 코딩"이라고 생각합니다.
내가 제안하는 것은 :
require('ifyoulieyougonnadie.php');
( 하지 include()
및 대체 등 defined or die
)에서 ifyoulieyougonnadie.php
논리 상수를 수행하고 다른 상수를 확인하고 스크립트 호출, 로컬 호스트 테스트 등을 수행 한 다음을 구현하십시오 die(), throw new Exception, 403
.
기본 index.php (Joomla 프레임 워크)와 ajaxrouter.php (내 프레임 워크)의 두 가지 가능한 진입 점이있는 자체 프레임 워크를 만들고 있으므로 진입 지점에 따라 다른 사항을 확인합니다. 이 ifyoulieyougonnadie.php
두 파일 중 하나에서 요청 이 없으면, shenanigans가 수행되고 있음을 알고 있습니다!
그러나 새로운 진입 점을 추가하면 어떻게됩니까? 걱정 마. 난 그냥 변경ifyoulieyougonnadie.php
하고 정렬했으며 '찾기 및 바꾸기'가 없습니다. 만세!
동일한 상수를 갖지 않는 다른 프레임 워크를 수행하기 위해 일부 스크립트를 이동하기로 결정하면 defined()
어떻게됩니까? ... 만세! ^ _ ^
나는이 전략이 개발을 훨씬 더 재미 있고 덜 만든다는 것을 발견했다.
/**
* Hmmm... why is my netbeans debugger only showing a blank white page
* for this script (that is being tested outside the framework)?
* Later... I just don't understand why my code is not working...
* Much later... There are no error messages or anything!
* Why is it not working!?!
* I HATE PHP!!!
*
* Scroll back to the top of my 100s of lines of code...
* U_U
*
* Sorry PHP. I didn't mean what I said. I was just upset.
*/
// defined('_JEXEC') or die();
class perfectlyWorkingCode {}
perfectlyWorkingCode::nowDoingStuffBecauseIRememberedToCommentOutTheDie();
보다 정확하게는이 조건을 사용해야합니다.
if (array_search(__FILE__, get_included_files()) === 0) {
echo 'direct access';
}
else {
echo 'included';
}
get_included_files () 는 포함 된 모든 파일의 이름을 포함하는 색인 배열을 리턴합니다 (파일이 실행 된 경우 파일이 포함되었고 해당 이름이 배열에 있음). 따라서 파일에 직접 액세스하면 파일 이름이 배열에서 첫 번째가되고 배열의 다른 모든 파일이 포함됩니다.
<?php
if (eregi("YOUR_INCLUDED_PHP_FILE_NAME", $_SERVER['PHP_SELF'])) {
die("<h4>You don't have right permission to access this file directly.</h4>");
}
?>
포함 된 PHP 파일의 상단에 위의 코드를 배치하십시오.
전의:
<?php
if (eregi("some_functions.php", $_SERVER['PHP_SELF'])) {
die("<h4>You don't have right permission to access this file directly.</h4>");
}
// do something
?>
다음 코드는 Flatnux CMS ( http://flatnux.altervista.org ) 에서 사용됩니다 .
if ( strpos(strtolower($_SERVER['SCRIPT_NAME']),strtolower(basename(__FILE__))) )
{
header("Location: ../../index.php");
die("...");
}
http와 cli 모두에서 작동하는이 PHP 전용 및 가변 솔루션을 찾았습니다.
함수를 정의하십시오.
function forbidDirectAccess($file) {
$self = getcwd()."/".trim($_SERVER["PHP_SELF"], "/");
(substr_compare($file, $self, -strlen($self)) != 0) or die('Restricted access');
}
직접 액세스하지 못하게하려는 파일의 함수를 호출하십시오.
forbidDirectAccess(__FILE__);
이 질문에 대해 위에서 제공된 대부분의 솔루션은 Cli 모드에서 작동하지 않습니다.
포함 파일을 웹 액세스 가능 디렉토리 외부에 저장하는 것은 몇 번 언급되었으며, 가능한 경우 좋은 전략입니다. 그러나 아직 언급하지 않은 다른 옵션은 포함 파일에 실행 가능한 코드가 포함되어 있지 않은지 확인하십시오 . 포함 파일이 단순히 함수와 클래스를 정의하고 그 이외의 코드가없는 경우 직접 액세스 할 때 빈 페이지가 생성됩니다.
항상 브라우저에서이 파일에 직접 액세스 할 수 있습니다. 아무것도하지 않습니다 . 일부 함수를 정의하지만 그 중 어느 것도 호출되지 않으므로 실행되지 않습니다.
<?php
function a() {
// function body
}
function b() {
// function body
}
PHP 클래스 만 포함하고 다른 것은없는 파일에도 동일하게 적용됩니다.
가능한 경우 파일을 웹 디렉토리 외부에 유지하는 것이 좋습니다.
system
코드라는 경로와 충돌하기 때문에 이라는 페이지를 가질 수없는 CMS를 사용합니다. 나는이 성가신 것을 발견한다.Javascript를 사용하여 서버에서만 요청을 가져 오는 다른 코드 줄을 추가 할 수있는 경우를 제외하고는 위조 될 수 있기 때문에 아래 방법에 결함이 있지만 아래 방법을 사용할 수 있습니다. 이 코드를 HTML 코드의 본문 섹션에 배치하면 오류가 표시됩니다.
<?
if(!isset($_SERVER['HTTP_REQUEST'])) { include ('error_file.php'); }
else { ?>
다른 HTML 코드를 여기에 넣으십시오
<? } ?>
이렇게 끝내십시오. 그래서 원하는 경우 오류 출력이 항상 본문 섹션에 표시됩니다.
당신이 할 수있는 일은 디렉토리를 비밀번호로 보호하고 index.php 파일을 제외한 모든 PHP 스크립트를 거기에 보관하는 것입니다. 포함시 비밀번호는 http 액세스에만 필요하므로 필요하지 않습니다. 또한 해당 디렉토리에 액세스 할 수있는 비밀번호가 있으므로 원하는 경우 스크립트에 액세스 할 수있는 옵션도 제공합니다. 디렉토리를위한 .htaccess 파일과 사용자를 인증하기 위해 .htpasswd 파일을 설정해야합니다.
cPanel 등을 통해 파일에 항상 액세스 할 수 있기 때문에 해당 파일에 정상적으로 액세스 할 필요가 없다고 생각 될 경우 위에 제공된 솔루션을 사용할 수도 있습니다.
도움이 되었기를 바랍니다
가장 쉬운 방법은 웹 디렉토리 외부에 포함을 저장하는 것입니다. 그렇게하면 서버는 서버에 액세스 할 수 있지만 외부 시스템은 액세스 할 수 없습니다. 유일한 단점은 서버의이 부분에 액세스 할 수 있어야한다는 것입니다. 단점은 설정, 구성 또는 추가 코드 / 서버 스트레스가 필요하지 않다는 것입니다.
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
일을 부드럽게 할 것입니다
BASEPATH
const
A의 설정 index.php
트리 구조의 맨 아래에 낳는 파일. CI는 URL을 다시 작성하므로 스크립트에 직접 액세스 할 필요가 없습니다.
이전에 언급 한 PHP 버전 확인 솔루션 :
$max_includes = version_compare(PHP_VERSION, '5', '<') ? 0 : 1;
if (count(get_included_files()) <= $max_includes)
{
exit('Direct access is not allowed.');
}