ホームページ  >  記事  >  バックエンド開発  >  PHP でのセーフ モード (safe_mode) の解析

PHP でのセーフ モード (safe_mode) の解析

藏色散人
藏色散人転載
2020-01-31 18:40:456335ブラウズ

PHP でのセーフ モード (safe_mode) の解析

PHP セーフ モードとは: safe_mode

PHP セーフ モードとは、簡単に言えば、セーフモードでphpを実行します。

php のセーフ モードは、複数のユーザー アカウントが存在する php オープン Web サーバー上に基本的な安全な共有環境を提供します。 PHP が Web サーバー上でセーフ モードで実行されている場合、一部の機能は完全に無効になり、使用可能な機能の一部は制限されます。

セーフ モードでは、ファイル システムにアクセスしようとする一部の機能が制限されます。 WebサーバーのユーザーIDを実行し、特定のファイルを操作する場合、そのファイルの読み書きのアクセス権限が必要ですが、PHPがこの制限機能を実装することは問題ありません。

セーフ モードがオンになっている場合、ローカル ファイルの読み取りまたは書き込みを試行すると、PHP は現在アクセスしているユーザーがターゲット ファイルの所有者であるかどうかを確認します。所有者でない場合、操作は無効になります。

(書き込み権限: 下位レベルのファイル アクセス権限では、システム オペレーティング システムでのファイルの読み取りまたは書き込みが許可される場合があります。これは、別のユーザーのファイルを操作できないようにするために、PHP のセーフ モードによって実現されます。もちろん、Web サーバーはグローバル書き込み権限で任意のファイルにアクセスできる場合があります。)

セーフ モードがオンになっていると、次の機能リストの機能が制限されます:

chdir、move_uploaded_file、chgrp、parse_ini_file、chown、rmdir、copy、rename、fopen、require、highlight_file、show_source、include、symlink、link、touch、mkdir、unlink

同じ、 PHP 拡張機能の一部の機能も影響を受けます。 (モジュールのロード: dl 機能はセーフ モードでは禁止されます。拡張機能をロードしたい場合は、php.ini で拡張機能のオプションを変更し、PHP の起動時にロードするだけです)

PHP セーフで開かれますmode システム プログラムを実行する必要がある場合は、safe_mode_exec_dir オプションで指定されたディレクトリ内のプログラムである必要があります。そうでない場合、実行は失敗します。実行が許可された場合でも、フィルタリングのために自動的にescapeshellcmd関数に渡されます。

コマンドを実行するための次の関数リストが影響を受けます:

exec,shell_exec,passthru,system,popen

さらに、バックマーク演算子 (`) も閉じられます。

セーフモードで実行した場合、エラーは発生しませんが、putenv関数は無効となります。同様に、PHP 環境変数を変更しようとする他の関数 set_time_limit および set_include_path も無視されます。

PHP セーフ モードをオンにする方法 (PHP5.3 にはセーフ モードがなくなることに注意してください)

PHP のセーフ モードをオンまたはオフにするには、次を使用します。 php.ini セーフモード オプション:

safe_mode=On(使用安全模式)
safe_mode=Off(关闭安全模式)

Apache の httpd.conf での VirtualHost の対応する設定方法

php_admin_flag safe_mode On(使用安全模式)
php_admin_flag safe_mode Off(关闭安全模式)
或者:
php_admin_value safe_mode1(使用安全模式)
php_admin_value safe_mode0(关闭安全模式)

セーフ モードを有効にした場合の影響:

When この関数は、ファイル システムにアクセスするときにファイル所有者チェックを実行します。デフォルトでは、ファイル所有者のユーザー ID がチェックされますが、ファイル所有者のグループ ID (gid) を変更できる場合は、safe_mode_gid オプションで指定します。

システム上に共有ライブラリ ファイルがある場合、インクルードまたは要求する必要が生じたときに、safe_mode_include_dir オプションを使用してパスを設定し、コードが正常に動作することを確認できます。 (インクルード パス:safe_mode_include_dir オプションを使用してさらに多くのインクルード パスを含める場合は、unix/linux システムではコロンを使用して、Windows では include_path オプションと同様にセミコロンを使用して区切ることができます)

たとえば、 /usr/local/include/php にあるファイルをセーフ モードでインクルードしたい場合は、オプションを次のように設定できます。

safe_mode_include_dir=/usr/local/include/php

インクルードされたファイルを実行する必要がある場合は、safe_mode_exec_dir オプションを設定できます。 。

たとえば、/usr/local/php-bin パス内のファイルを実行可能にする必要がある場合は、オプションを次のように設定できます:

safe_mode_exec_dir=/usr/local/php-bin

(実行可能: プログラムの場合実行するファイルは /usr/bin ディレクトリにあり、指定したオプションで実行できるパスにこれらのバイナリ ファイルを接続できます)

特定の環境変数を設定したい場合は、safe_mode_allowed_env_vars を使用できます。オプション。このオプションの値は、環境変数のプレフィックスです。デフォルトでは、php_ で始まる環境変数が許可されています。変更したい場合は、このオプションの値を設定できます。複数の環境変数プレフィックスを区切るには、カンマを使用します。

たとえば、タイム ゾーンの環境変数 tz が以下で許可されている場合、このオプションの値を次のように変更します。

safe_mode_allowed_env_vars=php_,tz

セーフ モードに加えて、php には他にも多くのモードが用意されています。 php のセキュリティを確保するための機能。

1. [PHP バージョン番号を隠す]

php.ini で Expose_php オプションを使用すると、Web サーバーから PHP レポート情報が漏洩するのを防ぐことができます。次のように:

expose_php=on

このセットアップ全体を使用すると、Web サーバーをターゲットとする自動スクリプトによる一部の攻撃を阻止できます。通常、http ヘッダー情報には次の情報が含まれます。

server:apache/1.3.33(unix)php/5.2.4mod_ssl/2.8.16openssl/0.9.7c

expose_php オプションをオンにすると、上記のヘッダー情報に PHP のバージョン情報は含まれなくなります。

当然,用户访问网站的时候同样能够看到.php的文件扩展名。如果你想整个的使用不同的文件扩展名,你需要在httpd.conf中找到如下这行:

addtype application/x-httpd.php

你就可以修改.php为任何你喜欢的文件扩展名。你能够指定任意多个的文件扩展名,中间使用空格进行分割。如果你想在服务器端使用php来解析.html和.htm文件的时候,那么你设置选项如下:

addtype application/x-httpd.html.htm

(解析html:配置你的web服务器使用php去解析所有的html文件,但是如果非服务器端代码也需要php去解析,会影响服务器的性能。静态页面你可以使用不同的扩展名,这样能够消除对php脚本引擎的依赖,增强性能。)

2、[文件系统安全]

安全模式限制了脚本所有者只能访问属于自己的文件,但是你可以使用open_basedir选现来指定一个你必须访问的目录。如果你指定了一个目录,php将拒绝访问除了该目录和该目录子目录的其他目录。open_basedir选项能够工作在安全模式之外。

限制文件系统只能访问/tmp目录,那么设置选项为:

open_basedir=/tmp

3、[函数访问控制]

你能够在disable_functions选项中使用逗号分割来设定函数名,那么这些函数将在php脚本中被关闭。这个设置能够工作在安全模式之外。

disable_functions=dl

当然,同样的你能够使用disable_classes选项来关闭对一些类的访问。

4、[数据库安全]

假设你的php脚本中包含一个基于表单值来执行的mysql查询:

$sql=”update mytable set col1=”.$_post[“value”].”where col2=’somevalue'”;
$res=mysql_query($sql,$db);

你希望$_post[“value”]包含一个整数值来更新你的列col1。可是,一个恶意用户能够输入一个分号在表单字段里,接着,是一段他/她想被任意执行的sql语句。

举例,假设下面是$_post[“value”]提交的值:

0;insert into admin_users(username,password) values (‘me’,’mypassword’);

那么当这个查询发送给mysql查询的时候,那么就变成了下面这条sql:

update mytable set col1=0;
insert into admin_users(username,password) values (‘me’,’mypassword’);
where col2=’somevalue';

这明显是一个有害的查询!首先这个查询会在mytable表里更新col1。这个并没有什么麻烦的,但是第二个表达式,它将执行insert表达式 来插入一个能登陆的新管理员。第三个表达式就废弃了,但同时sql解析器将抛出一个错误,这个有害的查询才完成。这个攻击就是大家常说的sql injection(注:sql注入)。

当然,sql injection存在一个问题,对方必须了解你的数据库结构。在这个例子中,攻击者是知道你有一个表admin_users,并且知道包含username和password字段,同时,存储的密码是没有加密的。

除了你自己,一般的网站访问者是不知道这些关于数据库的信息。可是,如果你使用了一个开发源代码的在线电子商务程序,或者使用一个自由的讨论版程序,这些数据表的定义都是已知的,或者有一些用户能够访问到你的数据库。

此外,你的脚本输出会提示一个查询错误,这些信息里包含了很多关于数据库结构的重要信息。在一个正常工作的网站上,你应该考虑设置 display_errors选项为off,并且使用log_errors来代替display_errors,把警告和错误信息插入到文件中。

(数据库权限:它是一个非常重要的东西,你只有正确的权限,才能通过脚本正确的连接数据库。你应该不要在脚本中使用管理员去连接数据库。如果你这么 做,那么一个攻击者将可能获取全部的数据库权限,并且包括其他相同服务器的权限。攻击者将可能运行grant或create user命令来获取更多的访问权限。)

如果你要防止sql injection攻击,你必须保证用户表单里提交的内容不是一个能够执行的sql表达式。

前一个例子中,我们使用一个整型值来进行更新。如果在单引号后面跟上一个字符串,这个攻击者在分号之前必须提交一个闭合的引用在整个sql表达式中。可是,当magic_quotes_gpc选项是开启的时候,在web表单中提交的引号将自动被转义。

为了防止被恶意的攻击者进行sql injection攻击,你应该总是确认提交的数据是合法的。如果你需要的是一个整数值,那么你可以使用is_numeric函数来测试这个表达值,或者使用settype函数来转换为一个数字,清除任何一个傻傻的sql语句。

如果你开发的程序需要几个提交的值在一个sql表达式里,你能够使用sprintf函数来构建一个sql字符串,使用格式化字符来指示数据类型的每个值。看下面的例子:

$sql=sprintf(“update mytable set col1=%d where col2=’%s'”, $_post[“number”], mysql_escape_string($_post[“string”]));

在上一个例子中,整个mysql的数据已经被使用,所以这个字符串已经通过mysql_escape_string函数进行过滤。对于其他数据库,你可以使用addslashes函数进行转义,或者使用其他方法。

php 関連の知識については、php チュートリアル をご覧ください。

以上がPHP でのセーフ モード (safe_mode) の解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はoschina.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。