Creating a custom configuration section with ConfigurationSection as described in this MSDN article is less straightforward when you want to use more than just attributes (e.g. text or CDATA elements):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
  <section name="stats" type="X.StatsSection, X"/>
  </configSections>
  <stats>
  <sql><![CDATA[SELECT * FROM tbl WHERE x < y]]></sql>
  </stats>
</configuration>

If you do as told, you’ll see this exception:

System.Configuration.ConfigurationErrorsException: The configuration section cannot contain a CDATA or text element.

Fortunately, creating a custom ConfigurationElement and overriding its DeserializeElement method does the trick:

class StatsSection : ConfigurationSection
{
  [ConfigurationProperty("sql")]
  public SqlElement Sql { get { return this["sql"] as SqlElement; } }
}

class SqlElement : ConfigurationElement
{
  protected override void DeserializeElement(XmlReader reader, bool s)
  {
    Value = reader.ReadElementContentAs(typeof(string), null) as string;
  }

  public string Value { get; private set; }
}

Not rocket science but (hopefully now less) difficult to find online.