如何在从public_html中找到一个文件目录后使用include返回public_html根文件

Kal*_*der 1 php security include root

基于一些非常有用的提示,我使用以下代码来包含PHP我的根目录之外的文件,看起来类似于:

define('WEB_ROOT', __DIR__);
define('APP_ROOT', dirname(__DIR__));
define('PHP_ROOT', APP_ROOT . DIRECTORY_SEPARATOR . 'application');


include(PHP_ROOT . DIRECTORY_SEPARATOR . 'bootstrap.php');
Run Code Online (Sandbox Code Playgroud)

我的问题是,例如,您可以根据bootstrap.php上面的内容包含代码.

如果那个PHP文件引导程序有自己的代码行,那么在public_html根文件夹中包含一个文件BACK ....如何编写一个代码呢?我这样做有些困难,我的目标是我不想在代码中填写实际的文字目录,我想避免文件遍历攻击

jed*_*rds 5

考虑这个项目结构:

/path/to/projectroot/index.php
                     header.php
                     include/inc.php

如果index.php有

include('include/inc.php');
Run Code Online (Sandbox Code Playgroud)

和inc.php有

include('header.php');
Run Code Online (Sandbox Code Playgroud)

你会得到那个错误,因为inc.php中的行会寻找

/path/to/projectroot/include/header.php  (doesn't exist)

/path/to/projectroot/header.php (does exist)

人们可以通过几种方式解决这个问题.

1:绝对路径

第一个也是最直接的是使用绝对路径.

如果index.php有

include('include/inc.php');
Run Code Online (Sandbox Code Playgroud)

和inc.php有

include('/path/to/projectroot/header.php');
Run Code Online (Sandbox Code Playgroud)

这会奏效.

2:带定义的绝对路径

类似于#1,如果index.php有

define('PROJECT_ROOT', '/path/to/projectroot/');
include(PROJECT_ROOT.'include/inc.php');
Run Code Online (Sandbox Code Playgroud)

和inc.php有

include(PROJECT_ROOT.'header.php');
Run Code Online (Sandbox Code Playgroud)

这会奏效.

更新:pichan的评论中所述,你可以在index.php中使用其中一个"魔术"常量,所以:

的index.php

define('PROJECT_ROOT', __DIR__.'/');
include(PROJECT_ROOT.'include/inc.php');
Run Code Online (Sandbox Code Playgroud)

和inc.php

include(PROJECT_ROOT.'header.php');
Run Code Online (Sandbox Code Playgroud)

注意我们在__DIR__这里添加一个尾部斜杠:

除非它是根目录,否则此目录名称没有尾部斜杠.

3:包括两者并隐藏错误

如果inc.php有

@include('header.php');    # Try this directory
@include('../header.php'); # Try parent directory
Run Code Online (Sandbox Code Playgroud)

这会奏效.[1]

4:除非另有说明,否则假设当前目录

如果index.php有

$rel_prefix_to_root = '../';
include('include/inc.php');
Run Code Online (Sandbox Code Playgroud)

和inc.php有

if(!isset($rel_path_to_root)){ $rel_path_to_root = ''; }
include($rel_path_to_root . 'header.php');
Run Code Online (Sandbox Code Playgroud)

这会奏效.

我对这些方法的看法

1和2基本相同,但2对于大型项目来说更容易一点,更常见,因为它允许您制作一个常量定义并在整个站点使用它.它还允许您在多个服务器上部署项目(放置在多个路径中),并且只需要在项目范围内更改一行,而不是在选项1的每个文件中更改一行.

3很可怕,不要这样做.有时你会看到它,你甚至可以在网上的教程中看到它.不要这样做.

应该避免4支持1或2.但是如果你有一些复杂的包含,这种方法可能是必要的.

一些说明:

[1]这是一个糟糕的主意.它有效,但不要这样做.