php에서 sql 인젝션을 방지하는 방법
【1. 서버 측 구성】
보안, PHP 코드 작성도 한 가지 측면이며 PHP 구성이 매우 중요합니다.
php를 수동으로 설치했습니다. php의 기본 구성 파일은 /usr/local/apache2/conf/php.ini에 있습니다. 가장 중요한 것은 php를 더 많이 실행할 수 있도록 php.ini에 내용을 구성하는 것입니다. 안전하게. PHP 전체의 보안 설정은 주로 phpshell 및 SQL 주입 공격을 방지하기 위한 것입니다. 먼저 편집 도구를 사용하여 /etc/local/apache2/conf/php.ini를 엽니다. 다른 방법으로 설치하면 구성 파일이 이 디렉터리에 없을 수 있습니다.
(1) PHP의 안전 모드 켜기
php의 안전 모드는 system(),
많은 파일을 동시에 조작하는 등 PHP의 일부 기능을 제어할 수 있는 매우 중요한 내장 보안 메커니즘입니다. time 이 함수에는 권한 제어 기능이 있으며 /etc/passwd와 같은 특정 키 파일을 허용하지 않습니다.
그러나 기본 php.ini는 안전 모드를 열지 않으며 우리가 엽니다:
safe_mode = on
(2) 사용자 그룹 보안
safe_mode가 켜져 있고 safe_mode_gid가 꺼진 경우 php 스크립트는 파일에 접근할 수 있으며, 동일한
그룹에 속한 사용자도 파일에 접근할 수 있습니다.
다음과 같이 설정하는 것을 권장합니다:
safe_mode_gid = off
설정하지 않으면 파일 조작이 필요한 경우 등 당사 서버 웹사이트 디렉토리에 있는 파일을 조작하지 못할 수 있습니다.
(3) 안전 모드에서 프로그램의 홈 디렉터리 실행
안전 모드가 켜져 있지만 특정 프로그램을 실행하려는 경우 실행할 프로그램의 홈 디렉터리를 지정할 수 있습니다.
safe_mode_exec_dir = D:/usr/bin
일반적으로 , 어떤 프로그램을 실행해야 하는지가 아니므로 시스템 프로그램 디렉터리를 실행하지 않는 것이 좋습니다.
디렉터리를 가리킨 다음 다음과 같이 실행해야 하는 프로그램을 복사할 수 있습니다.
safe_mode_exec_dir = D:/tmp/cmd
그러나 , 어떤 프로그램도 실행하지 않는 것이 좋습니다. 그런 다음 웹 디렉터리를 가리킬 수 있습니다:
safe_mode_exec_dir = D:/usr/www
(4) 안전 모드에서 파일 포함
안전 모드에서 일부 공용 파일을 포함하려면 옵션을 수정하세요.
safe_mode_include_dir = D:/usr/www/include/
사실 일반적으로 PHP 스크립트에 포함되는 파일은 프로그램 자체가 작성되어 있으며 이는 특정 필요에 따라 설정할 수 있습니다.
(5) PHP 스크립트가 액세스할 수 있는 디렉토리를 제어합니다.
open_basedir 옵션을 사용하여 PHP 스크립트가 지정된 디렉토리에만 액세스할 수 있도록 제어합니다. 이렇게 하면 PHP 스크립트가
액세스해서는 안 되는 파일에 액세스하지 못하게 되어 phpshell이 제한됩니다. 일반적으로 웹사이트 디렉토리에만 액세스하도록 설정할 수 있습니다.
open_basedir = D:/usr/www
(6) 위험한 기능 끄기
안전 모드가 켜져 있으면 기능 금지가 필요하지 않지만 여전히 안전을 위해 고려하세요. 예를 들어,
명령을 실행할 수 있는 system()이나
phpinfo() 및 PHP 정보를 볼 수 있는 기타 함수를 포함한 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 버전 정보 유출 차단
해커가 서버에서 PHP 버전 정보를 얻는 것을 방지하기 위해 http 헤더에서 정보 유출을 차단할 수 있습니다. header:
expose_php = Off
예를 들어 해커가 telnet www.12345.com 80 이라면 PHP 정보를 볼 수 없습니다.
(8) 전역 변수 등록 끄기
POST 또는 GET을 사용하여 제출된 변수를 포함하여 PHP로 제출된 변수는 자동으로 전역 변수로 등록되며 직접 액세스할 수 있습니다.
이것은 매우 중요합니다. 서버 안전하지 않아 전역 변수로 등록할 수 없으므로 등록 전역 변수 옵션을 끕니다.
register_globals = Off
물론 이렇게 설정한 경우 합리적인 방법을 사용하여 획득해야 합니다. GET 제출된 변수 var를 얻는 것과 같은 해당 변수,
그런 다음 이를 얻으려면 $_GET['var']를 사용해야 합니다. PHP 프로그래머는 이에 주의해야 합니다.
(9) SQL 인젝션을 방지하려면 Magic_quotes_gpc를 켜세요
SQL 인젝션은 아주 작은 경우에는 웹사이트 백엔드가 침범당하고, 최악의 경우 서버 전체가 붕괴되는 경우가 있으니 주의하세요. . php.ini에는 다음 설정이 있습니다.
magic_quotes_gpc = Off
이 기능은 기본적으로 꺼져 있습니다. 켜져 있으면 사용자가 제출한 쿼리를 자동으로 SQL로 변환합니다.
예를 들어 '를 '로 변환합니다. SQL 주입 효과를 방지하는 데 중요합니다. 따라서 다음과 같이 설정하는 것이 좋습니다.
magic_quotes_gpc = On(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('select|insert|update|delete|'| function verify_id($id=null) { if (!$id) { exit('没有提交参数!'); } // 是否为空判断 elseif (inject_check($id)) { exit('提交的参数非法!'); } // 注射判断 elseif (!is_numeric($id)) { exit('提交的参数非法!'); } // 数字判断 $id = intval($id); // 整型化 return $id; } ?>
那么我们就能够进行校验了,于是我们上面的程序代码就变成了下面的:
<?php if (inject_check($_GET['id'])) { exit('你提交的数据非法,请检查后重新提交!'); } else { $id = verify_id($_GET['id']); // 这里引用了我们的过滤函数,对$id进行过滤 echo '提交的数据合法,请继续!'; } ?>
好,问题到这里似乎都解决了,但是我们有没有考虑过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); // 把 '_'过滤掉 $str = str_replace("%", "\%", $str); // 把' % '过滤掉 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); // 把 '_'过滤掉 $post = str_replace("%", "\%", $post); // 把' % '过滤掉 $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 중국어 웹사이트의 기타 관련 기사를 참조하세요!