CKeditor and ASP.NET

30. May 2010 11:19

I have seen many developers give and follow bad advice in regards to using CKeditor with ASP.NET, hence I am writing this blog post to give what I believe is the correct advice.

Background

CKeditor is a WYSIWYG text/HTML editor (for websites) developed using JavaScript. It is the successor to FCKeditor, but this time it is super fast, WAI-AA compliant, has a jQuery adaptor and is gaining some pretty nice features. I've used TinyMCE and FCKeditor in the past, both had their advantages and disadvantages, but I think CKeditor has fixed all the the disadvantages of the previous generation of web HTML editors and is now one of the best editors available. Plus it's open source, and free.

A screenshot of CKeditor

The Problem

CKeditor is often used to replace a HTML textarea field in a form, and when the form is submitted the CKeditor content is submitted as HTML. This causes a problem because ASP.NET implements a security feature that blocks posted form data containing HTML, with an error message that reads: “A potentially dangerous Request.Form value was detected". This is Request Validation, and is a preventative method against users submiting bad and malicious data to your application.

90% of the time I see developers deactivating request validation (ValidateRequest=”false”) on their pages and websites just to get CKeditor to work, and this is my message to those developers, and to you, to STOP doing this - and do it properly! Deactivating request validation is taking down a layer of your website's defense mechanism, which I think we can all agree is not the most desirable solution.

Note: FCKeditor, the predecessor to CKeditor, has an offical ASP.NET user control - and CKeditor is having an official one developed too. There are also unoffical CKeditor user controls. What I am able to show/discuss does not necessarily apply to these user controls; as they should already be doing the things I am about to show - apart from the section "Taking it further".

The Solution

CKeditor, thankfully, has an configuration setting specifically to work around ASP.NET's request validation without having to disable it. In CKeditor's config.js we need to add the following:

config.htmlEncodeOutput = true;

Just to ensure things are clear, here is an example config.js file:

CKEDITOR.editorConfig = function (config) {

    config.skin = 'kama';
    config.resize_enabled = false;
    config.toolbarCanCollapse = false;
    config.height = 300;
    config.htmlEncodeOutput = true;

};

The configuration setting above tells CKeditor that the HTML needs to be encoded before posting it back to the server; this works around ASP.NET's request validation because there is no pure HTML being posted back to the server. Next we need to decode it in our code-behind (if you're using WebForms) or our controller (if you're using MVC). I'm going to demonstrate this using two semi-complete examples.

C# MVC Example

The key line of interest is no.13:

public class MyController : System.Web.Mvc.Controller
{
	[HttpPost]
	public ActionResult Create(ViewModel viewModel1)
	{
		if (ModelState.IsValid)
		{
			var entity1 = new Entity();
			entity1.Title = viewModel1.Title;
			
			//Decode the value that CKeditor returned
			entity1.Text = viewModel1.Text
			.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
			
			DatabaseService.Save(entity1);
			return RedirectToAction("Index");
		}
		return View();
	}
}

VB.NET WebForms Example

The key line of interest is no.14:

Public Class MyPage
	Inherits System.Web.Page
	
	Protected Sub Button1_Click(ByVal sender As Object, _
		ByVal e As System.EventArgs) Handles Button1.Click
		
		'Do some validation
		
		Dim entity1 As New Entity
		entity1.Title = TextBox1.Text
		
		'Decode the value that CKeditor returned
		entity1.Text = CKTextBox2.Text _
		.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&")
		
		DatabaseService.Save(entity1)
		
		'Do whatever
		
	End Sub
	
End Class

Now that we are decoding posted form data, perhaps we should encode it before we send the form and editor to the user's web browser. It's basically the same as decoding the data, but in reverse. This time I am going to provide shortened examples:

C# MVC Example

viewModel1.Text = entity1.Text
	.Replace("&","&amp;").Replace(">","&gt;").Replace("<","&lt;");

VB.NET WebForms Example

CKTextBox2.Text = entity1.Text _
	.Replace("&","&amp;").Replace(">","&gt;").Replace("<","&lt;")

Taking it further

Now, we have CKeditor fully working with ASP.NET's request validation. But it doesn't stop a malicious user from posting bad HTML code - we need to "sanitize" it. Luckily there is a .NET library for that called AntiXSS. Using this library, we can reduce the chance of users successfully submitted bad data:

//Retrieve CKeditor value
untrustedFormValue = TextBox1.Text
	.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");

//Sanitize untrusted form value
trustedFormValue = AntiXss.GetSafeHtmlFragment(untrustedFormValue);

Summary

I have shown how you can utilise CKeditor on your ASP.NET website without having to take down the defense mechanism called request validation, and then sanitize the data inputted by the user. However, I have not shown how to use CKeditor when using jQuery/AJAX with ASP.NET - this will be another post that I'm leaving for later!

Twitter Facebook MySpace Digg

Tags: ,

About Me

I'm 24 years old, and live in the UK. I'm a software/web developer who mostly dabbles in .NET, ASP.NET MVC, C#, JavaScript, jQuery, and CSS.

Month List

Recent Posts