PHP Markdown/文件编辑器安全性


PHP Markdown/file editor Security

所以我正在做一个超级简单的博客,它使用rss.reader的markdown格式来发布帖子。对于我想发帖的人来说,这是非常简单但又复杂的。所以我创建了一个简单的"文件创建者",如果你的遗嘱类型表单使用hallojs的话。它为hallowjs获取转换后的markdown代码,并根据用户输入将其写入一个文件(2014-04-08_markdownfile-test.md)。它由index.html和post.php组成。除了一个问题外,这一切都很顺利:

有三个特定的"网站",任何这些博客文章都可以在上面创建,所以我包含了一个选择选项,这意味着我的目录现在可以使用,很容易被恶意破解者选中。作为一种安全措施,我已经包含了必要的.htaccess,以"拒绝所有人"并防止任何人潜入,但根据表单,他们可以很容易地注入自己的文件并运行它们,所以我正在试图找到一种方法来防止这种情况。我的第一个想法是在php文件中声明目录,而不是简单地显示在index.html上。然而,我觉得我自己很困惑,现在我正在兜圈子。以下是我的资料来源:

index.htm

 <article>
 <div class="editable" contenteditable="true"> //hallojs user-input
 <h1>Create new post</h1>
 <p> Please edit your blog post! :D
 </p>
 </div>
 </article>
 <form name="form1" method="post" action="post.php">
 <table width="100%" border="0" cellspacing="1" cellpadding="3">
 <textarea id="source" id="textfield" name="textfield"></textarea> //markdown output
 <tr>
 <td width="16%">Date</td>
 <td width="2%"></td>
 <td width="82%">
 <input name="date" type="text" id="date" size="50"></td>
 </tr>
 <tr>
 <td>Title</td>
 <td></td>
 <td><input name="title" type="text" id="title" size="50"></td>
 </tr>
 <tr>
 <td>Which Site?</td>
 <td></td>
 <td><select name="dir">
 <option value="path/to/dir1">Site1</option>
 <option value="path/to/dir2">Site2</option>
 <option value="path/to/dir3">Site3</option>
 </select></td></tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td><input type="submit" name="Submit" value="Submit"></td>
 </table></form>

post.php

 <?php
 $date        = $_POST['date'];
 $title       = $_POST['title'];
 $underscore  = "_";
 $dir         = $_POST['dir'];
 $myfile      = fopen("$dir/$date$underscore$title.md", 'w');
 if ($_SERVER['REQUEST_METHOD'] == "POST")
 {
          $myfile or die("Can't open file for writing.");
          fwrite($myfile, $_POST['textfield']);
          fclose($myfile);
          echo "Content saved. ";
          echo "Your file: <b>" ;
          echo $date;
          echo $underscore;
          echo $title . ".md</b> ";
          echo "was successfully created!";
    }

// Print the form     
 ?>

我想也许可以把下拉列表的值改为"dir1…dir2…dir3.",然后做这样的事情,但我只想确保它是安全的:

 <?
 $dir = $_POST['dir'];
 if($dir == "dir1")
 {
 $dir == "path/to/dir1"
 }elseif { $dir =="dir2")
 {
 $dir == "path/to/dir2"
 }; // etc..

我认为仅仅从外观上看是行不通的。任何帮助都将不胜感激。哦,如果有人配置了我的$下划线问题,那就太棒了。文件名输出的日期后必须有下划线。无论我试着只放下划线,它都不起作用,否则我会收到诸如"$date_尚未设置"之类的错误,并且我的文件只以$title.md输入命名。真的很有趣。

Sooo。。。我想通了!以下是我所做的更改,以防有人出现同样的问题(这将是一个奇怪的问题):

<?php
$date        = $_POST['date'];
$title       = $_POST['title'];
$underscore  = "_";
$dir         = "";
if(!isset($_POST['dir'])) $_POST['dir']="";
switch($_POST['dir']) {
case "Site1":    $dir = "path/to/site1"; break;
case "Site2":    $dir = "path/to/site2"; break;
case "Site3":    $dir = "path/to/site3"; break;    
}
$myfile      = fopen("$dir/$date$underscore$title.md", 'w');
if ($_SERVER['REQUEST_METHOD'] == "POST"){
$myfile or die("Can't open file for writing.");
fwrite($myfile, $_POST['textfield']);
fclose($myfile);
echo "Content saved. ";
echo "Your file: <b>" ;
echo $date;
echo $underscore;
echo $title . ".md</b> ";
echo "was successfully created to the website: <b>";
echo $_POST['dir'];
echo "</b>";
    }

// Print the form
?>

我很惊讶它能起作用,因为我不知道我到底在做什么——这看起来很合乎逻辑,所以我这么做了。

有趣的是,我最初的想法奏效了,但其他地方看起来都非常丑陋,所以我决定使用switch语句,因为它们非常干净和脏。我还没有弄清楚$下划线的问题。。。但在大多数情况下,它现在更安全了!:}