1

这是我的代码:

<?php
if(isset($_GET['p']))
{
    $nshortname = strip_tags($_GET['p']);
    $check = mysql_query("SELECT * FROM pages WHERE `shortname` = '$nshortname'");

    if(mysql_num_rows($check) == 0) 
    {
        echo '<center><font size="50" style="font-weight:bold;">404</font><br>Appears this page is a dead end</center>';
    }
    else
    {
        $h = mysql_fetch_array($check);
        //post details
        $title = $h["title"];
        $content = $h["content"];
        $shortname = $h["shortname"];
        // Start of page content
        echo '

        <p>
        <font size="5pt">'.$title.'</font><br><hr>
        '.$content.'<br>
        ';
        // End of page content
    }
} 
else
{
    echo 'No page has been selected to view';
}
?>

它究竟做了什么,它从我的数据库中抓取页面并读取它们,例如,如果我在该表中有一个名为“test”的页面,我可以通过http://mylink.com/?p=test访问它。虽然我想出了一个问题。在其中一个来自我想要包含的数据库的页面上,但是当我在数据库字段中键入它并返回到它显示的页面时,它什么也没有显示。

我在浏览器中找到页面的源代码,发现代码变成了<!--?php include "inc/extra/plugins/header/slideshow.php"?-->

有谁知道我怎样才能把它从变成<!--?并让我的包含代码工作。

4

2 回答 2

3

我会告诫不要使用eval()未知内容。基本上,内容来自您的数据库,但这并不能保证它作为代码执行是安全的!有很多方法可能导致错误或做一些恶意的事情。

但是您的代码中还有其他危险的安全漏洞。您应该了解如何防御SQL 注入漏洞和跨站点脚本 (XSS)漏洞和文件包含漏洞。

  • mysql_real_escape_string()如果您仍在使用已弃用的 ext/mysql,请使用。但如果可以的话,切换到 mysqli 或 PDO_mysql 并使用带参数的准备好的语句。

  • 始终使用 输出动态内容htmlspecialchars()。如果内容包含 Javascript 代码怎么办?它可能会引起恶作剧。

  • 永远不要eval()将任意内容作为代码。您无法控制该内容是什么,或者当您执行它时它可以做什么。

  • 尽可能严格——如果您想包含文件,请将文件名与内容分开存储(例如,在单独的列中),并将其用于包含文件。

这是一个示例,其中一些问题已在您的代码中修复:

<?php

if(isset($_GET['p']))
{
    $nshortname = mysql_real_escape_string($_GET['p']);
    $check = mysql_query("SELECT * FROM pages WHERE `shortname` = '$nshortname'");

    if(mysql_num_rows($check) == 0) 
    {
        echo '<center><font size="50" style="font-weight:bold;">404</font><br>Appears this page is a dead end</center>';
    }
    else
    {
        $h = mysql_fetch_array($check);
        //post details
        $title = htmlspecialchars($h["title"]);
        $content = htmlspecialchars($h["content"]);
        $shortname = $h["shortname"];
        // Start of page content
        echo '

        <p>
        <font size="5pt">'.$title.'</font><br><hr>
        '.$content.'<br>
        ';
        // End of page content

        // Start of include
        if ($h["include"]) {
          // strip out anything like "../../.." etc. 
          // to make sure this is only a simple filename.
          $include = basename($h["include"]);
          include "inc/extra/plugins/header/{$include}.php";
        }
        // End of plugin inclusion
    }
} 
else
{
    echo 'No page has been selected to view';
}
?>

另请查看http://www.sitepoint.com/php-security-blunders/http://phpsec.org/projects/phpsecinfo/


回复您的评论:

要允许一组有限的基本 HTML,您需要使用的最佳工具是http://htmlpurifier.org

我不确定对您的包含显示代码而不是工作该说些什么。我刚刚对此进行了测试,以下两个文件似乎完全按预期工作:

foo.php

<?php

echo "<h1>START FOO</h2>";
if ($_GET["include"]) {
    $include = basename($_GET["include"]);
    include "./{$include}.php";
}
echo "<h1>END FOO</h2>";

bar.php

<?php
echo "<h2>BAR</h2>";
于 2013-11-03T12:33:13.587 回答
0

如果你有一个变量 $content 是带有 php 的 html,你可以使用
eval("?>" . $content . "<?php");
这将输出 $content 已经处理了所有的<?php ?>标签。

于 2013-11-03T11:25:14.937 回答