简体   繁体   English

如何保护您的网站免受PHP中的本地文件包含和SQL注入?

[英]How do you protect your website from Local File Inclusion & SQL Injection in PHP?

如何保护您的网站免受本地文件包含和SQL注入(PHP)的侵害?

There are numerous measures to be taken. 有许多措施可以采取。 Be sure to sanitize all input before storing in the database. 在存储到数据库之前,请务必清理所有输入。 I suggest using mysql_real_escape_string() on all data that will be stored. 我建议对将要存储的所有数据使用mysql_real_escape_string() Limit character-input to reasonable lengths, and be sure you're getting the TYPE of data you are expecting for that field. 将字符输入限制为合理的长度,并确保获得该字段期望的数据类型。 Lock multiple attempts to submitting specific areas of data. 锁定多次尝试提交特定数据区域。 Crawl the contents of uploaded files looking for malicious patterns. 抓取上传文件的内容以查找恶意模式。

Wikibooks has a chapter on SQL Injection; Wikibooks有一章关于SQL注入;

The list goes on and on. 这个清单一直在继续。 Fortunately, even a little effort in this area can patch a great number of vulnerabilities. 幸运的是,即使在这方面做了一点努力也可以修补大量的漏洞。

Prepared statements for SQL (see PDO::prepare() ) or proper escaping ( PDO::quote() ). SQL的预备语句(请参阅PDO::prepare() )或正确的转义( PDO::quote() )。

For local paths you need to carefully sanitize input (brutal, but safe: preg_replace('/[^az]/','',$str) ) or avoid using untrusted data in paths altogether (use IDs, predefined strings, etc.) 对于本地路径,您需要仔细清理输入(野蛮但安全: preg_replace('/[^az]/','',$str) )或避免在路径中使用不受信任的数据(使用ID,预定义字符串等)。 )

for protecting against SQL injection i'd recommend using PDO ( http://us3.php.net/pdo ). 为了防止SQL注入,我建议使用PDO( http://us3.php.net/pdo )。 There's extensions etc that you need which can block adoption but it's good stuff. 你需要的扩展等可以阻止采用,但它是好东西。

Personally I use a home brewed DB access layer that all my queries go thru which implements a bunch of nice-to-have's including mysql_real_escape_string() 就个人而言,我使用自制的DB访问层,我的所有查询都通过它实现了一堆包含mysql_real_escape_string()

By "local file inclusion", do you mean the case where you call include() or suchlike on a path constructed from user input, such as in a very simple file-based CMS or similar? 通过“本地文件包含”,是指在用户输入构造的路径上调用include()或类似的情况,例如在非常简单的基于文件的CMS或类似的情况下? If so, the answer is basically the same as for SQL injection - you have to sanitise the input. 如果是这样,答案基本上与SQL注入相同 - 您必须清理输入。

Sanitising file paths requires you to set some ground rules about where files can be included from, and to ruthlessly reject any input which doesn't conform. 清理文件路径需要您设置一些关于文件可以包含在哪里的基本规则,并且无情地拒绝任何不符合的输入。 For example, if you're just including files by name in a subdirectory, then you might apply the following basic algorithm: 例如,如果您只是在一个子目录中按名称包含文件,那么您可以应用以下基本算法:

  1. Reject file names which contain . 拒绝包含的文件名. , .. or / (or \\ under Windows) ../ (或Windows下的\\
  2. Limit file names to basic alphanumeric characters 将文件名限制为基本字母数字字符
  3. Prepend the include directory name and append the appropriate extension 添加包含目录名称并附加相应的扩展名

The PHP documentation has some more information about filesystem security . PHP文档提供了有关文件系统安全性的更多信息。 You could also set up open_basedir to confine file access to within a specific directory tree, but that is part of PHP's "safe mode", which is deprecated (and will be removed in PHP 6.0), owing to it not really being very safe. 你也可以设置open_basedir来限制特定目录树中的文件访问,但这是PHP的“安全模式”的一部分,这是不推荐使用的(并且将在PHP 6.0中删除),因为它并不是非常安全。

Like others have said, mysql\\_real\\_escape\\_string() is the safest method to prevent SQL injection. 像其他人所说的那样, mysql\\_real\\_escape\\_string()是防止SQL注入的最安全的方法。 I use a custom DB interface class for all my SQL, which passes all the needed variables through a sanitize() function. 我为所有SQL使用自定义数据库接口类,它通过sanitize()函数传递所有需要的变量。 Here's that sanitize function stripped from the class in case you wanna take a look at it. 这是从课堂上剥离的清理功能,以防你想看看它。

/**
* Sanitize variable for querying
*
* @param mixed $var         The variable to sanitize
* @param bool $deep         Will inspect the string deeper, converting 'null' to NULL and adding '' around strings
* @param mixed $numstrings  Whether or not to treat numbers as strings (ie add quotes)
* @return $var
*/
function sanitize($var, $deep = true, $numstrings = false) {
    if (is_array($var)) {   //run each array item through this function (by reference)
        foreach ($var as $key=>$val) {
        $var[$key] = sanitize($val, $deep, $numstrings);
        }
    }
    else if (is_null($var) || ( $deep && preg_match('/^null$/i', $var) > 0 ) ) {   //convert null variables to SQL NULL
        $var = "NULL";
    }
    else if (is_bool($var)) {   //convert boolean variables to binary boolean
        $var = ($var) ? 1 : 0;
    }
    else if ($numstrings && is_string($var)) {
        $var = mysql_real_escape_string($var);
        if ($quotes) {
        $var = "'". $var ."'";
        }
    }
    else if (!is_numeric($var)) { //clean strings
        $var = mysql_real_escape_string($var);
        if ($deep) {
        $var = "'". $var ."'";
        }
    }
    return $var;
}

As for "local-file inclusion", I use two different methods. 至于“本地文件包含”,我使用两种不同的方法。 Keep in mind that the safest technique is to keep sensitive files in a place not accessible from the web. 请记住,最安全的技术是将敏感文件保存在无法从Web访问的位置。

If it's only a file or to I don't want the world to see, I simply append '.ht' to the filename. 如果它只是一个文件或者我不希望世界看到,我只需将“.ht”附加到文件名中。 Apache, by default, denies access to files beginning with '.ht'. 默认情况下,Apache拒绝访问以“.ht”开头的文件。 Just make sure not to name your files the same as Apache config files (.htaccess, .htpasswd, etc). 只需确保不要将文件命名为与Apache配置文件(.htaccess,.htpasswd等)相同。

If you have multiple files that you don't want accessed, keep them all in a sub-directory of your site (again, sensitive files should be elsewhere). 如果您有多个不想访问的文件,请将它们全部保存在站点的子目录中(同样,敏感文件应该在其他位置)。 Then in the sub-directory, add a .htaccess file that denies access to the directory (they are still accessible via PHP). 然后在子目录中添加一个拒绝访问目录的.htaccess文件(它们仍然可以通过PHP访问)。

#this is all you need in the file
Order Allow , Deny
Deny from all

在提交之前避免SQL注入加密密码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM