I found a hole in BlogEngine.NET that allows anyone to delete and approve comments.
UPDATE 7/11: Fixed in 1.4.0.12 Verify the Hole
- Add a test comment to your blog
- Refresh the blog posting to retrieve latest source
- View source of blog posting
- Find guid of comment to delete (see line 103 below)
<div id="id_9c2b8578-1dde-421e-94ff-5ea7e0d82012" class="comment">
<p class="date">7/10/2008 4:13:35 PM</p>
<p class="gravatar"><img src="http://www.gravatar.com/avatar/b642b4217b34b1e8d3bd915fc65c4452.jpg?s=80&d=http%3a%2f%2fjvance2%2fblogengine%2fmonster.axd%3fseed%3db642b4217b%26size%3d80" alt="Test3" /></p>
<p class="content">asfasdfafdasd sa afsdfdsaas </p>
<p class="author">
Test3
<img src="/blogengine/pics/flags/us.png" class="flag" alt="us" />
</p>
</div>
- Request a POST to BlogPostUrl.aspx?deletecomment=guid
- Refresh the page and notice comment is deleted
Patch the Hole
You can patch the hole by updating the Page_Load event in the CommentView.ascx.cs file by checking for an authenticated user (lines 117,118, & 127)
protected void Page_Load(object sender, EventArgs e)
{
if (Post == null)
Response.Redirect(Utils.RelativeWebRoot);
if (!Page.IsPostBack && !Page.IsCallback)
{
if (Page.User.Identity.IsAuthenticated)
{
if (Request.QueryString["deletecomment"] != null)
DeleteComment();
if (!string.IsNullOrEmpty(Request.QueryString["approvecomment"]))
ApproveComment();
if (!string.IsNullOrEmpty(Request.QueryString["approveallcomments"]))
ApproveAllComments();
}
string path = Utils.RelativeWebRoot + "themes/" + BlogSettings.Instance.Theme + "/CommentView.ascx";
Repeat the steps given above to verify that the hole has been patched.
In the process of adding OpenID support to the comment system in BlogEngine.NET I found myself deep in a rabbit hole of refactoring. This comment security issue is just one of the things I've found during my journey. I've reported the issue on the BlogEngine.NET Issue Tracker. I think it is important to point out that the patch above is just a quick fix. The proper solution is to put authorization checks in the business layer (the BlogEngine.Core.Post business object in this case).