ホームページ  >  記事  >  バックエンド開発  >  PHPでSQLインジェクションを防ぐ方法のまとめ

PHPでSQLインジェクションを防ぐ方法のまとめ

angryTom
angryTomオリジナル
2019-11-08 17:09:046848ブラウズ

PHPでSQLインジェクションを防ぐ方法のまとめ

#SQL インジェクションを防ぐ php メソッド

[1. サーバー側の設定]

安全性、PHP コード作成は 1 つの側面であり、PHP 構成は非常に重要です。

PHP を手動でインストールしました。PHP のデフォルト設定ファイルは

/usr/local/apache2/conf/php.ini にあります。最も重要なことは、php でコンテンツを設定することです。 ini. を使用すると、php をより安全に実行できるようになります。 PHP全体のセキュリティ設定は主にphpshellやSQLインジェクションからの攻撃を防ぐためのものですが、ゆっくり解説していきます。まず、編集ツールを使用して /etc/local/apache2/conf/php.ini を開きますが、他の方法でインストールした場合は、設定ファイルがこのディレクトリに存在しない可能性があります。

(1) PHP のセーフ モードをオンにする

php のセーフ モードは、PHP の一部の機能を制御できる非常に重要な組み込みセキュリティ メカニズムです。

system(),

同時に、多くのファイル操作機能はアクセス許可によって制御され、/etc/passwd、

などの特定のキー ファイルは許可されません。デフォルトの php.ini ではセーフ モードがオンになりません。これをオンにします。

safe_mode = on

(2) ユーザー グループ セキュリティ

safe_mode がオンの場合、safe_mode_gid は次のようになります。オフにすると、php スクリプトがファイルにアクセスできるようになり、同じ

グループ内のユーザーもファイルにアクセスできるようになります。

これを設定することをお勧めします:

safe_mode_gid = off

これを設定しないと、操作が必要な場合など、サーバー Web サイトのディレクトリ内のファイルを操作できなくなる可能性があります。ファイル。

(3) セーフ モードでプログラムを実行するためのホーム ディレクトリ

セーフ モードがオンになっているが、特定のプログラムを実行したい場合は、そのプログラムを次のように指定できます。メイン ディレクトリ:

safe_mode_exec_dir = D:/usr/bin

通常、プログラムを実行する必要はないため、システム プログラム ディレクトリを実行しないことをお勧めします。ディレクトリ

と次に、実行する必要があるプログラムをコピーします。例:

safe_mode_exec_dir = D:/tmp/cmd

ただし、プログラムは実行しないことをお勧めします。その場合は、Web ディレクトリを指定できます:

safe_mode_exec_dir = D:/usr/www

( 4) セーフ モードでファイルを含める

一部のパブリック ファイルをセーフ モードで含める場合は、オプションを変更します:


safe_mode_include_dir = D:/usr/www/include/

実際、通常、含まれるファイルはphp スクリプトはプログラム自体によって記述されており、特定のニーズに応じて設定できます。

(5) PHP スクリプトがアクセスできるディレクトリを制御する

open_basedir オプションを使用して、PHP スクリプトが指定されたディレクトリにのみアクセスできるように制御します。これにより、PHP スクリプトがアクセスできないようになります。 accessing

アクセスすべきではないファイルにより、phpshell の害はある程度制限されます。通常は、Web サイトのディレクトリにのみアクセスするように設定できます:

open_basedir = D:/usr/www

(6) オフにする危険な機能

セーフモードがオンになっている場合、機能の禁止は必要ありませんが、安全性を考慮しております。たとえば、

コマンドを実行できる system() や、PHP 情報を表示できる

phpinfo() やその他の関数を含む PHP 関数を実行したくないと感じた場合、

disable_functions = system,passthru,exec,shell_exec,popen,phpinfo

ファイルやディレクトリの操作を禁止したい場合は、多くのファイル操作を閉じることができます。

disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir, rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown

上記は、一般的に使用されるファイル処理関数の一部のみを示しています。また、上記の実行コマンド機能とこの機能を組み合わせると、

はほとんどの phpshell に耐えることができます。


(7) http ヘッダー内の PHP バージョン情報の漏洩を阻止する

ハッカーによる http ヘッダー内の PHP バージョン情報の取得を防ぐため、たとえば、ハッカーが www.12345.com 80 に Telnet した場合、PHP 情報は表示されなくなります。


(8) グローバル変数の登録をオフにする

PHP で送信された変数 (POST または GET を使用して送信された変数を含む) は、グローバル変数として自動的に登録されます。

これはサーバーにとって非常に安全ではないため、グローバル変数として登録することはできないため、グローバル変数の登録オプションをオフにします:


expose_php = Off

もちろん、これが設定されている場合は、GET によって送信された変数 var を取得するなど、適切な方法を使用して対応する変数を取得する必要があります。


その後、$_GET['var'] を使用して、を取得する場合、PHP プログラマーはこれに注意する必要があります。

(9) magic_quotes_gpc を開いて SQL インジェクションを防止します

SQL インジェクションは非常に危険な問題であり、小規模な場合には Web サイトのバックエンドが侵入される可能性があり、深刻な場合には Web サイトのバックエンドが侵害される可能性があります。サーバー全体が崩壊する可能性があります。したがって、注意してください。 php.ini には次の設定があります:

register_globals = Off

これはデフォルトではオフになっています。オンにすると、ユーザーが送信した SQL クエリが自動的に変換されます。

たとえば、convert 'これは、SQL インジェクションの防止に重要な役割を果たします。したがって、次のように設定することをお勧めします:

magic_quotes_gpc = Off

(10) エラー メッセージ制御

通常、PHP はデータベースに接続されていない場合、またはデータベースに接続されていない場合にエラーを表示します。一般的なエラー メッセージ php スクリプトは、 の場合にインクルードされます。

前的路径信息或者查询的SQL语句等信息,这类信息提供给黑客后,是不安全的,所以一般服务器建议禁止错误提示:

display_errors = Off

如果你却是是要显示错误信息,一定要设置显示错误的级别,比如只显示警告以上的信息:

error_reporting = E_WARNING & E_ERROR

当然,我还是建议关闭错误提示。

(11) 错误日志

建议在关闭display_errors后能够把错误信息记录下来,便于查找服务器运行的原因:

log_errors = On

同时也要设置错误日志存放的目录,建议根apache的日志存在一起:

error_log = D:/usr/local/apache2/logs/php_error.log

注意:给文件必须允许apache用户的和组具有写的权限。

MYSQL的降权运行

新建立一个用户比如mysqlstart

net user mysqlstart fuckmicrosoft /add
net localgroup users mysqlstart /del

不属于任何组

如果MYSQL装在d:\mysql ,那么,给 mysqlstart 完全控制 的权限

然后在系统服务中设置,MYSQL的服务属性,在登录属性当中,选择此用户 mysqlstart 然后输入密码,确定。

重新启动 MYSQL服务,然后MYSQL就运行在低权限下了。

如果是在windos平台下搭建的apache我们还需要注意一点,apache默认运行是system权限,

这很恐怖,这让人感觉很不爽.那我们就给apache降降权限吧。

net user apache fuckmicrosoft /add
net localgroup users apache /del

ok.我们建立了一个不属于任何组的用户apche。

我们打开计算机管理器,选服务,点apache服务的属性,我们选择log on,选择this account,我们填入上面所建立的账户和密码,

重启apache服务,ok,apache运行在低权限下了。

实际上我们还可以通过设置各个文件夹的权限,来让apache用户只能执行我们想让它能干的事情,给每一个目录建立一个单独能读写的用户。

这也是当前很多虚拟主机提供商的流行配置方法哦,不过这种方法用于防止这里就显的有点大材小用了。 

【二、在PHP代码编写】

防止SQL Injection (sql注射)

SQL 注射应该是目前程序危害最大的了,包括最早从asp到php,基本上都是国内这两年流行的技术,基本原理就是通过对提交变量的不过滤形成注入点然后使恶意用户能够提交一些sql查询语句,导致重要数据被窃取、数据丢失或者损坏,或者被入侵到后台管理。

那么我们既然了解了基本的注射入侵的方式,那么我们如何去防范呢?这个就应该我们从代码去入手了。

我们知道Web上提交数据有两种方式,一种是get、一种是post,那么很多常见的sql注射就是从get方式入手的,而且注射的语句里面一定是包含一些sql语句的,因为没有sql语句,那么如何进行,sql语句有四大句:select 、update、delete、insert,那么我们如果在我们提交的数据中进行过滤是不是能够避免这些问题呢?

于是我们使用正则就构建如下函数:

PHP代码

<?php         
 function inject_check($sql_str)    
 {    
 return eregi(&#39;select|insert|update|delete|&#39;|    
 function verify_id($id=null)    
 {    
 if (!$id) { exit(&#39;没有提交参数!&#39;); } // 是否为空判断    
 elseif (inject_check($id)) { exit(&#39;提交的参数非法!&#39;); } // 注射判断    
 elseif (!is_numeric($id)) { exit(&#39;提交的参数非法!&#39;); } // 数字判断    
 $id = intval($id); // 整型化        
 return $id;    
 }    
 ?>

那么我们就能够进行校验了,于是我们上面的程序代码就变成了下面的:

<?php    
   if (inject_check($_GET[&#39;id&#39;]))    
   {    
   exit(&#39;你提交的数据非法,请检查后重新提交!&#39;);    
   }    
   else    
   {    
   $id = verify_id($_GET[&#39;id&#39;]); // 这里引用了我们的过滤函数,对$id进行过滤    
   echo &#39;提交的数据合法,请继续!&#39;;    
   }    
   ?>

 好,问题到这里似乎都解决了,但是我们有没有考虑过post提交的数据,大批量的数据呢?

比如一些字符可能会对数据库造成危害,比如 ' _ ', ' %',这些字符都有特殊意义,那么我们如果进行控制呢?还有一点,就是当我们的php.ini里面的magic_quotes_gpc = off的时候,那么提交的不符合数据库规则的数据都是不会自动在前面加' '的,那么我们要控制这些问题,于是构建如下函数:

<?php       
  function str_check( $str )    
  {    
  if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否打开    
  {    
  $str = addslashes($str); // 进行过滤    
  }    
  $str = str_replace("_", "\_", $str); // 把 &#39;_&#39;过滤掉    
  $str = str_replace("%", "\%", $str); // 把&#39; % &#39;过滤掉    
        
  return $str;    
  }    
  ?>

最后,再考虑提交一些大批量数据的情况,比如发贴,或者写文章、新闻,我们需要一些函数来帮我们过滤和进行转换,再上面函数的基础上,我们构建如下函数:

<?php     
    function post_check($post)    
    {    
    if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否为打开    
    {    
    $post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤    
    }    
    $post = str_replace("_", "\_", $post); // 把 &#39;_&#39;过滤掉    
    $post = str_replace("%", "\%", $post); // 把&#39; % &#39;过滤掉    
    $post = nl2br($post); // 回车转换    
    $post= htmlspecialchars($post); // html标记转换       
    return $post;    
    }    
?>

注:关于SQL注入,不得不说的是现在大多虚拟主机都会把magic_quotes_gpc选项打开,在这种情况下所有的客户端GET和POST的数据都会自动进行addslashes处理,所以此时对字符串值的SQL注入是不可行的,但要防止对数字值的SQL注入,如用intval()等函数进行处理。但如果你编写的是通用软件,则需要读取服务器的magic_quotes_gpc后进行相应处理。

更多PHP相关知识,请访问PHP中文网

以上がPHPでSQLインジェクションを防ぐ方法のまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。