略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: 隐藏 PHP

2024-12-21

隐藏 PHP

一般而言,通过隐藏来实现安全是最脆弱的安全方式之一。但在某些情况下,每一点额外的安全都是值得的。

一些简单的方法可以帮助隐藏 PHP,这可能会减慢攻击者试图找到系统弱点的速度。 通过在 php.ini 文件中设置 expose_php 为 off, 可以减少能获得的有用信息。

另一个策略是配置 web 服务器(例如 apache)通过 PHP 解析不同的文件类型, 无论是通过 .htaccess 文件还是 apache 的配置文件,都可以设置能误导攻击者的文件扩展名:

示例 #1 把 PHP 隐藏为另一种语言

# 使 PHP 代码看起来像其他代码类型
AddType application/x-httpd-php .asp .py .pl
或者干脆彻底隐藏它:

示例 #2 使用未知的扩展名作为 PHP 的扩展名

# 使 PHP 代码看起来像未知的类型
AddType application/x-httpd-php .bop .foo .133t
或者隐藏它为 HTML 代码,这样会有轻微的性能影响,因为所有的 HTML 都将通过 PHP 引擎进行解析:

示例 #3 使用 HTML 作为 PHP 扩展名

# 使所有的 PHP 代码看起来像 HTML
AddType application/x-httpd-php .htm .html
要让此方法生效,必须把 PHP 文件的扩展名改为以上的扩展名。这样就通过隐藏来提高了安全性,这是一个小的预防措施,几乎没有缺点。
add a noteadd a note

User Contributed Notes 25 notes

up
28
rustamabd at google mail
15 years ago
So far I haven't seen a working rewriter of /foo/bar into /foo/bar.php, so I created my own. It does work in top-level directory AND subdirectories and it doesn't need hardcoding the RewriteBase.

.htaccess:

RewriteEngine on

# Rewrite /foo/bar to /foo/bar.php
RewriteRule ^([^.?]+)$ %{REQUEST_URI}.php [L]

# Return 404 if original request is /foo/bar.php
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

# NOTE! FOR APACHE ON WINDOWS: Add [NC] to RewriteCond like this:
# RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$" [NC]
up
14
anon at example dot com
8 years ago
The session name defaults to PHPSESSID.  This is used as the name of the session cookie that is sent to the user's web browser / client. (Example: PHPSESSID=kqjqper294faui343o98ts8k77).

To hide this, call session_name() with the $name parameter set to a generic name, before calling session_start().  Example:

session_name("id");
session_start();

Cheers.
up
7
Anonymous
18 years ago
Keep in mind, if your really freaked out over hiding PHP, GD will expose you.

Go ahead - make an image with GD and open with a text editor.. Somewhere in there you'll see a comment with gd & php all over it.
up
8
CD001
11 years ago
It's a good idea to "hide" PHP anyway so you can write a RESTful web application.

Using Apache Mod Rewrite:

RewriteEngine On
RewriteRule ^control/([^/]+)/(.*)$ sitecontroller.php?control=$1&query=$2

You then use a function like the following as a way to retrieve data (in a zero indexed fashion) from the $_GET superglobal.

<?php
function myGET() {
 
$aGet = array();

  if(isset(
$_GET['query'])) {
   
$aGet = explode('/', $_GET['query']);
  }

  return
$aGet;
}
?>

This is only a really basic example of course - you can do a lot with Mod Rewrite and a custom 'GET' function.
up
6
Pyornide
13 years ago
The idea of hiding the X-Powered-By in PHP is a flawed attempt at establishing security. As the manual indicates, obscurity is not security. If I were exploiting a site, I wouldn't check what scripting language the site runs on, because all that would matter to me is exploiting it. Hiding the fact that you use [x] language isn't going to prevent me from bypassing poor security.
up
8
mmj
18 years ago
You can see if somebody's using PHP just by adding the following to the end of the URL:
?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
If the page is using PHP, this will show the PHP credits.

Setting expose_php to Off in php.ini prevents this.
up
5
ldemailly at qualysNOSPAM dot com
18 years ago
adding MultiViews to your apache Options config
lets you hide/omit .php in the url without any rewriting, etc...
up
7
marpetr at NOSPAM dot gmail dot com
16 years ago
I think the best way to hide PHP on Apache and Apache itself is this:

httpd.conf
-------------
# ...
# Minimize 'Server' header information
ServerTokens Prod
# Disable server signature on server generated pages
ServerSignature Off
# ...
# Set default file type to PHP
DefaultType application/x-httpd-php
# ...

php.ini
------------
; ...
expose_php = Off
; ...

Now the URLs will look like this:
http://my.server.com/forums/post?forumid=15

Now hacker knows only that you are using Apache.
up
4
yasuo_ohgaki at yahoo dot com
20 years ago
To hide PHP, you need following php.ini settings

expose_php=Off
display_errors=Off

and in httpd.conf

ServerSignature Off
(min works, but I prefer off)
up
3
sandaimespaceman at gmail dot com
13 years ago
Set INI directive "expose_php" to "off" will also help.
You can spoof your PHP to ASP.NET by using:
<?php
error_reporting
(0);
header("X-Powered-By: ASP.NET");
?>
up
3
Anonymous
19 years ago
PS. If you want to use pretty URLs (i.e. hide your .php extensions) AND you have safe-mode=on, the previous example (ForceType) won't work for you.  The problem is that safe-mode forces Apache to honor trailing characters in a requested URL.  This means that:

http://www.example.com/home

would still be processed by the home script in our doc root, but for:

http://www.example.com/home/contact_us.html

apache would actually look for the /home/contact_us.html file in our doc root.

The best solution I've found is to set up a virtual host (which I do for everything, even the default doc root) and override the trailing characters handling within the virtual host.  So, for a virtual host listening on port 8080, the apache directives would look like this:

<VirtualHost *:8080>
    DocumentRoot /web/doc_root
    Alias /home "/web/doc_root/home.php"
    AcceptPathInfo On
</VirtualHost>

Some people might question why we are overriding the trailing characters handling (with the AcceptPathInfo directive) instead of just turning safe-mode=off.  The reason is that safe mode sets global limitations on the entire server, which can then be turned on or left off for each specific virtual host.  This is the equivilent of blocking all connections on a firewall, and then opening up only the ones you want, which is a lot safer than leaving everything open globally, and assuming your programmers will never overlook a possible security hole.
up
2
benjamin at sonntag dot fr
17 years ago
In response to the previous messages, for apache, there is a easier way to set files without "." to be executed by PHP, just put this in a ".htaccess" file :

DefaultType  application/x-httpd-php
up
1
info at frinteractives dot com
6 years ago
try this
RewriteEngine On

# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ http://example.com/folder/$1 [R=301,L]

# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ http://example.com/folder/$1 [R=301,L]

# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ $1.php [L]
up
2
l0rdphi1 at liquefyr dot com
18 years ago
More fun includes files without file extensions.

Simply add that ForceType application/x-httpd-php bit to an Apache .htaccess and you're set.

Oh yea, it gets even better when you play with stuff like the following:

<?php
substr
($_SERVER['PATH_INFO'],1);
?>

e.g. www.example.com/somepage/55

And:

<?php
foreach ( explode('/',$_SERVER['PATH_INFO']) as $pair ) {
    list(
$key,$value) = split('=',$pair,2);
   
$param[$key] = stripslashes($value);
}
?>

e.g. www.example.com/somepage/param1=value1/param2=value2/etc=etc

Enjoy =)
up
2
m1tk4 at hotmail dot com
19 years ago
I usually do:

<code>
RewriteEngine on<br>
RewriteOptions inherit<br>
RewriteRule (.*)\.htm[l]?(.*) $1.php$2 [nocase]<br>
</code>

in .htaccess. You'll need mod_rewrite installed for this .
up
1
istvan dot takacsNOSPAM at hungax dot com
20 years ago
And use the
ServerTokens min
directive in your httpd.conf to hide installed PHP modules in apache.
up
0
php at user dot net
18 years ago
What about this in a .htaccess file :

RewriteEngine on
RewriteRule    ^$    /index.php    [L]
RewriteRule    ^([a-zA-Z0-9\-\_/]*)/$    /$1/index.php    [L]
RewriteRule    ^([a-zA-Z0-9\-\_/]*)\.(html|htm)$    /$1.php    [L]
RewriteRule    ^([a-zA-Z0-9\-\_/]*)$    /$1.php    [L]

Typing "sub.domain.foo/anything" loads "/anything/index.php" if 'anything' is a directory, else it loads "/anything.php".

I'm sure you can find mutch better, but it works great on my site :)
up
-2
simon at carbontwelevedesign dot co dot uk
15 years ago
I use the following in the .htaccess document

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

then the following simple code

<?php

$permalinks
= explode("/",$_SERVER['REQUEST_URI']);

$varone = $permalinks[1];
$vartwo = $permalinks[2];

...

?>