我只是要管理一个网站,但对前一个家伙编写的代码不太确定。我在下面粘贴了登录过程,您可以看看并告诉我是否存在任何安全漏洞吗?乍一看,似乎可以通过SQL注入或操作cookie和?m =参数来进入。
定义('CURRENT_TIME',时间()); / / 当前时间。
定义('ONLINE_TIME_MIN',(CURRENT_TIME-BOTNET_TIMEOUT)); //最短时间为“在线”状态。
定义('DEFAULT_LANGUAGE','en'); //默认语言。
定义('THEME_PATH','theme'); //以文件夹为主题。
// HTTP请求。
定义('QUERY_SCRIPT',基本名($ _SERVER ['PHP_SELF']));
定义('QUERY_SCRIPT_HTML',QUERY_SCRIPT);
定义('QUERY_VAR_MODULE','m'); //变量包含当前模块。
定义('QUERY_STRING_BLANK',QUERY_SCRIPT。'?m ='); //一个空的查询字符串。
定义('QUERY_STRING_BLANK_HTML',QUERY_SCRIPT_HTML。'?m ='); //在HTML中为空查询字符串。
定义('CP_HTTP_ROOT',str_replace('\ \','/',(!空($ _SERVER ['SCRIPT_NAME'])?目录名($ _SERVER ['SCRIPT_NAME']):'/')))); // CP的根。
//会话cookie。
定义('COOKIE_USER','p'); //用户名中的cookie。
定义('COOKIE_PASS','u'); //用户密码在cookie中。
定义('COOKIE_LIVETIME',CURRENT_TIME + 2592000)//终身Cookie。
定义('COOKIE_SESSION','ref'); //存储会话的变量。
define('SESSION_LIVETIME',CURRENT_TIME + 1300)//会话的生存时间。
///////////////////////////////////////////////////// //////////////////////////////
//初始化。
///////////////////////////////////////////////////// //////////////////////////////
//连接数据库。
如果(!ConnectToDB())死亡(mysql_error_ex());
//连接主题。
require_once(THEME_PATH。'/ index.php');
//管理登录。
如果(!为空($ _GET [QUERY_VAR_MODULE]))
(
/ / 登录表单。
if(strcmp($ _GET [QUERY_VAR_MODULE],'login')=== 0)
(
UnlockSessionAndDestroyAllCokies();
if(isset($ _POST ['user'])&&isset($ _POST ['pass']))
(
$ user = $ _POST ['user'];
$ pass = md5($ _POST ['pass']);
//检查登录。
if(@ mysql_query(“从cp_users WHERE名称='中的SELECT ID。加斜杠($ user)。”'AND pass ='“。加斜杠($ pass)。”'AND flag_enabled ='1'LIMIT 1')&& @ mysql_affected_rows()== 1)
(
if(isset($ _POST ['remember'])&&$ _POST ['remember'] == 1)
(
setcookie(COOKIE_USER,md5($ user),COOKIE_LIVETIME,CP_HTTP_ROOT);
setcookie(COOKIE_PASS,$ pass,COOKIE_LIVETIME,CP_HTTP_ROOT);
)
LockSession();
$ _SESSION ['名称'] = $用户;
$ _SESSION ['Pass'] = $ pass;
// UnlockSession();
标头(“位置:”。QUERY_STRING_BLANK。“首页”);
)
否则ShowLoginForm(true);
死 ();
)
ShowLoginForm(false);
死 ();
)
//输出
if(strcmp($ _GET ['m'],'注销')=== 0)
(
UnlockSessionAndDestroyAllCokies();
标头(“位置:”。QUERY_STRING_BLANK。“登录”);
死 ();
)
)
///////////////////////////////////////////////////// //////////////////////////////
//检查登录数据。
///////////////////////////////////////////////////// //////////////////////////////
$ logined = 0,//标志意味着,我们zalogininy。
//登录会话。
LockSession();
if(!空($ _SESSION ['name'])&&!空($ _SESSION ['pass']))
(
if(($ r = @ mysql_query(“ SELECT * FROM cp_users WHERE name ='”。addslashes($ _SESSION ['name'])。 “'AND flag_enabled ='1'LIMIT 1”))))已登录= @ mysql_affected_rows();
)
//通过cookie登录。
如果($已登录!== 1&&!空($ _COOKIE [COOKIE_USER])&&!空($ _COOKIE [COOKIE_PASS]))
(
if(($ r = @ mysql_query(“ SELECT * FROM cp_users WHERE MD5(name)='”。加号($ _COOKIE [COOKIE_USER])。“'AND pass ='”。 'AND flag_enabled ='1'LIMIT 1“))))已登录= @ mysql_affected_rows();
)
/ / 无法登入。
如果($登录!== 1)
(
UnlockSessionAndDestroyAllCokies();
标头(“位置:”。QUERY_STRING_BLANK。“登录”);
死 ();
)
//获取用户数据。
$ _USER_DATA = @ Mysql_fetch_assoc($ r);
如果($ _USER_DATA === false)死亡(mysql_error_ex());
$ _SESSION ['名称'] = $ _USER_DATA ['名称'];
$ _SESSION ['Pass'] = $ _USER_DATA ['pass'];
//连接语言。
if(@ strlen($ _USER_DATA ['language'])!= 2 | |!SafePath($ _USER_DATA ['language'])| |!file_exists('system / lng。'。$ _ USER_DATA ['language']。 '。php'))$ _ USER_DATA ['language'] = DEFAULT_LANGUAGE;
require_once('system / lng。'。$ _ USER_DATA ['language']。'。php');
UnlockSession();
参考方案
是的,此代码中有一些漏洞。
这可能是一个问题:
define ( 'QUERY_SCRIPT', basename ($ _SERVER [ 'PHP_SELF']));
PHP_SELF
不好,因为攻击者可以控制此变量。例如,当您使用以下URL访问脚本时,尝试打印PHP_SELF
:http://localhost/index.php/test/junk/hacked
。尽可能避免使用此变量,如果要使用它,请确保对其进行消毒。使用此变量时,通常会看到XSS出现。
第一个漏洞:
setcookie (COOKIE_USER, md5 ($ user), COOKIE_LIVETIME, CP_HTTP_ROOT);
setcookie (COOKIE_PASS, $ pass, COOKIE_LIVETIME, CP_HTTP_ROOT);
这是一个相当严重的漏洞。如果攻击者在您的应用程序中注入了SQL,则他们可以获得md5哈希值和用户名并立即登录,而不必破坏md5()
哈希值。就像您以明文形式存储密码一样。
该会话漏洞有两个方面,它也是一个“不朽会话”,会话ID必须始终是大的随机生成的值,这些值会过期。如果它们没有过期,那么它们将更容易被暴力破解。
您永远不要重新发明轮子,在应用程序开始时调用session_start()
,这将自动生成过期的安全会话ID。然后,使用会话变量(例如$_SESSION['user']
)来跟踪浏览器是否实际登录。
第二个漏洞:
$ pass = md5 ($ _POST [ 'pass']);
事实证明md5()
是不安全的,因为有意产生了冲突。 md5()绝对不能用作密码。您应该使用sha2家族的成员,sha-256或sha-512是不错的选择。
第三个漏洞:
CSRF
我看不到任何CSRF保护您的身份验证逻辑。我怀疑您的应用程序中的所有请求都容易受到CSRF的攻击。
PHP getallheaders替代 - php我正在尝试从服务器上的apache切换到nginx。唯一的问题是我在PHP脚本中使用的getallheaders()函数,该函数不适用于Nginx。我已经尝试过用户在getallheaders函数上的php站点上提供的注释,但这并不返回所有请求标头。请告诉我如何解决这个问题。我真的想切换到Nginx。 参考方案 您仍然可以使用它,但是您必须像这里一样重新定义…
php Singleton类实例将在多个会话中保留吗? - php举一个简单的例子,如果我想计算一个不使用磁盘存储的脚本的命中次数,我可以使用静态类成员来执行此操作吗?用户1:<?php $test = Example::singleton(); $test->visits++; ?> 用户2:<?php $test = Example::singleton(); $test->visits+…
PHP:将字符串拆分为字母和数字部分的最佳方法 - php我有几个格式的字符串AA11 AAAAAA1111111 AA1111111 分离字符串的字母和数字部分的最佳方法(最有效)? 参考方案 如果它们都是一系列字母,然后是一系列数字,并且没有非字母数字字符,那么sscanf()可能比regexp更有效$example = 'AAA11111'; list($alpha,$numeric) =…
php-casperjs获取内部文本 - php我正在为casperjs使用php包装器-https://github.com/alwex/php-casperjs我正在网上自动化一些重复的工作,我需要访问一个项目的innerText,但是我尚不清楚如何从casperjs浏览器访问dom。我认为在js中我会var arr = document.querySelector('label.input…
PHP strtotime困境 - php有人可以解释为什么这在我的服务器上输出为true吗?date_default_timezone_set('Europe/Bucharest'); var_dump( strtotime('29.03.2015 03:00', time()) === strtotime('29.03.2015 04:00…