• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 位置: php 中文手册 -> php 语言

    php 安全

    PHP 作为一种强大的语言,无论是以模块还是 CGI 的方式安装,它的解释器都可以在服务器上访问文件、运行命令以及创建网络连接等。这些功能也许会给服务器添加很多不安全因素,但是只要正确地安装和配置 PHP,以及编写安全的代码,那么 PHP 相对于 Perl 和 C 来说,是能创建出更安全的 CGI 程序的。而且,也可以在可用性和安全性之间找到一个很好的平衡点。

    PHP 可能会被用在很多不同的方面,因此,PHP 内置的选项以方便用户对其进行配置。虽然众多的选项可以使 PHP 完成很多工作,但是对这些选项的设定以及对服务器的配置很可能会产生安全问题。

    PHP 的选项与其语法一样,具有很高的灵活性。使用 PHP,可以在只有 shell 用户权限的环境下创建完善的服务器端程序,或者在被严格限制环境下使用它来完成服务器端包含(Server-Side Includes)而无需承但太大的风险。如何建立这样一种环境,其安全性如何,很大程度上取决于 PHP 的开发者。

    本章以一些常规的安全建议作开头,讲述如何在不同的环境下尽可能地提高安全性,以及介绍对于不同安全级别的一些编程原则。

    总则

    绝对安全的系统是不存在的,因此安全业界常用的方法有助于平衡可用性和风险。对用户提交的每一个变量都进行双重验证可能是一个很负责任的行为,但会导致用户必须花很多时间去填写一张复杂无比的表格,从而迫使某些用户尝试绕过安全机制。

    最好的安全机制应该能在不防碍用户,并且不过多地增加开发难度的情况下做到能满足需求。实际上,一些安全问题往往会发生在这种过度强化安全机制的系统上。

    不要忘记著名的等强原则:一个系统的的强度是由它最薄弱的环节决定的(译者注:相当于木桶原理)。如果所有的事务都基于时间、地点、事务种类进行详细的记录,而用户验证却只依靠一个 cookie,那么用户所对应的事务记录的可信度就被大大剥弱了。

    调试代码的时候一定要记住,就算是一个简单的页面也很难对所有可能发生的情况进行检测:对你不满的雇员不一定会输入如你所愿的东西,黑客也有足够的时间研究你的系统,当然,你的宠物猫也会跳到你的键盘上。这就是为什么必须检查所有的代码,去发现哪里可以引入不正当的数据,然后对代码改进、简化或者增强。

    互联网上充满了为了成名而破坏你的代码、攻击你的网站并输入不正当数据的人,总之他们会使你的生活充满乐趣。无论是大网站还是小网站,只要能和互联网连接,就会成为一个目标。很多黑客程序并不理会网站的大小,只会机械地扫描 IP 地址并找寻受害者。我们希望那个不要是你。

    If a single file has to be included than I use the following
    index.php ( where the file is gonna be included )
    ___________
    <?php
      define('thefooter', TRUE);
      include('folder/footer.inc.php');
    ?>
    and the footer file (for example) looks this way then
    footer.inc.php ( the file to be inluded )
    ___________
    <?php
      defined('thefooter') or die('Not with me my friend');
      echo('Copyright to me in the year 2000');
    ?>
    So when someone tries to access the footer.php file directly he/she/it will get the "Not with me my friend" messages written on the screen. An alternative option is to redirect the person who wants to access the file directly to a different location, so instead of the above code you would have to write the following in the footer.inc.php file.
    <?php
      defined('thefooter') or header('Location: http://www.location.com');
      echo('Copyright to me in the year 2000');
    ?>
    In normal case a redirection to an external site would be annoying to the visitor, but since this visitor is more interested in hacking the site than in reading the content, I think it's only fair to create such an redirection. We dont' realy want someome like this on our sites.
    For the file protection I use .htaccess in which I say to protect the file itself and every .inc file
    <Files ~ "^.*\.([Hh][Tt]|[Ii][Nn][Cc])">
    Order allow,deny
    Deny from all
    Satisfy All
    </Files>
    The .htaccess file should result an Error 403 if someone tries to access the files directly. If for some reason this shouldn't work, then the "Not with me my friend" text apears or a redirection (depending what is used)
    In my eyes this looks o.k. and safe.
    If your PHP pages include() or require() files that live within the web server document root, for example library files in the same directory as the PHP pages, you must account for the possibility that attackers may call those library files directly. Any program level code in the library files (ie code not part of function definitions) will be directly executable by the caller outside of the scope of the intended calling sequence. An attacker may be able to leverage this ability to cause unintended effects.The most robust way to guard against this possibility is to prevent your webserver from calling the library scripts directly, either by moving them out of the document root, or by putting them in a folder configured to refuse web server access. With Apache for example, create a .htaccess file in the library script folder with these directives:Order Allow,DenyDeny from any
    Password hashing should be linked here:
    http://php.net/manual/en/faq.passwords.php
    I'd recommend a 404 over a 403 considering a 403 proves there is something worth hacking into.index.php:<?phpdefine('isdoc',1);include('includes/include.sqlfunctions.php');// Rest of code for index.php?>include.sqlfunctions.php (or other include file):<?phpif(isdoc !== 1) // Not identical to 1{ header('HTTP/1.1 404 Not Found'); echo "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>404 Not Found</title>\n</head>"; echo "<body>\n<h1>Not Found</h1>\n<p>The requested URL ".$_SERVER['REQUEST_URI']." was not found on this server.</p>\n"; echo "<hr>\n".$_SERVER['SERVER_SIGNATURE']."\n</body></html>\n"; // Echo output similar to Apache's default 404 (if thats what you're using) exit;}// Rest of code for this include?>
    
    Remember that security risks often don't involve months of prep work or backdoors or whatever else you saw on Swordfish ;) In fact one of the bigges newbie mistakes is not removing "<" from user input (especially when using message boards) so in theory a user could secerely mess up a page or even have your server run php scripts which would allow them to wreak havoc on your site.
    In Reply to djjokla and othersConsider placing all incude files as mentioned before in a seperate folder containing a .htaccess containing a Order Deny,Allowthe create a index file, which is intended to handle ALL request made to you php application, then call it with index.php?view=indexthe index file could look a bit like this:<?phpswitch($_GET['view']){ case 'index': include('libs/index.php'); break; default: include('libs/404.php'); break;}?>this could be an array or something even more creative. it actually does'nt matter how you do it... running all pages through one central script has one big advantage.... CONTROL.at any givin time, you can easily implement access control to functions without forgetting crucial files.
    Since many users can not modify apache configurations or use htaccess files, the best way to avoid unwanted access to include files would be a line at the beginning of the include-file:
    <?php if (!defined('APPLICATION')) exit; ?>
    And in all files that are allowed to be called externally:
    <?php define('APPLICATION', true); ?>
       Balu
    chroot is NOT a security feature. Don't use it as one. Please read the man pages of chroot to understand what its really used for
    best bet is to build php as cgi, run under suexec, with chroot jailed users. Not the best, but fairly unobtrusive, provides several levels of checkpoints, and has only the detriment of being, well, kinda slow. 8)
    Good Dharma tokens which are basically in the feed somewhere that allow users that are not reprogramming and injecting to get into the site.Change this POST AJAX call URL every couple minutes to exclude users who didn't follow your portal. You can combine this with where they came from. Just in the case of advertised click-thrus.You can make a perfectly good token from time() and some measure away from it every ~5th minute(?). Balance the load by free token grasping at login, or even if they just got to the site. And don't let them into the feed past the designated 5th minute, or algorithmic sum for your timed change of the guard, without knowledge of the token. This can be caught up by passing variables across pages. Directly injecting the POST token with a curl to your own site. And combining that like a session ID.
    How about not putting the php code in the web-root at all...?
    You can create a public directory with the css, html, etc and index.php there. Then use the include_path setting to point to the actual php code, eg...
    webstuff
     phpcode
     public
      images
      css
      index.php
    then set the include path to "../phpcode" and, as php is executed from the directory of the script, all should be well.
    I'd also call the main index "main.page", or something else, instead of "index.php" and change the web server default index page. That way you cant get hit by things trawlling the web for index pages.
    A correction to previous post by Dave Mink.<Files ~ "\.inc$"> Order allow,deny Deny from all Satisfy All</Files>Will not stop something likehttp://www.yourserver.com/includefile.inc?pointlessvar=blahblahHere is something more sophisticated for this task:<Location ~ "/[^ ](?=\.inc(\?[^ ]*)?)/"> Options None Order Allow, Deny Deny from All AllowOverride None Satisfy All</Location>Also, consider placing in your httpd.conf<Location ~ "/[^ ](?=\.phps(\?[^ ]*)?)/"> Options None Order Allow, Deny Deny from All AllowOverride None Satisfy All</Location>
    For real security you should consider providing chrooted jail's for your users.
    First, q much simpler solution to preventing people from viewing code inside of an includable file would be to give include file an extension that ends with php (e.g. myFile.inc.php).
    Secondly, and more importantly, why on earth would you want to put program-level code in an include file? By that I mean something life this:
    myFile.inc.php
    --------------------------------
    ...
    if ($var = 'whatever')
      // connect to the database
    else
      // do something else.
    --------------------------------
    An include file should not contain logic! Rather, it is an encapsulated unit of code that should not do anything on its own unless asked to. To implement this ideology, consider including function definitions only in your include files, then once you include them in the script, call such functions from within your program (i.e. the script that included the inc file). If you don't know the names of the functions ab initio, use call_user_func() or call_user_func_array() and pass it the name of the function that's dependent on context.
    If you MUST put program-level logic in your include files, consider simply putting it in the program!
    Why should you consider this? How about variable name clashes for a starter! You can think of more, I am shure!
    Hope that helped