ConfigurationErrorsException/SecurityException/FileIOPermission reading application .config file during NLog instantiation

StackOverflow https://stackoverflow.com/questions/20421278

Question

I'm getting a weird exception when trying to initialize NLog instance as a static class member (update: this is happening in a desktop app which is targeting .NET 4.0).

The problem is, I'm getting it only on one specific client machine, and can't reproduce on any of my development configurations. Can someone point me in a direction, what should I look for?

PS: User tried to run the app with administrator rights as well, getting same exception.

System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for nlog: Request for permission of type "System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral,     PublicKeyToken=b77a5c561934e089" failed. (C:\Users\XXX\Desktop\Test.exe.Config line 9) ---> System.Security.SecurityException: Request for permission of type "System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" failed.
   in System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   in System.Security.CodeAccessPermission.Demand()
   in System.AppDomainSetup.VerifyDir(String dir, Boolean normalize)
   in NLog.Internal.Fakeables.AppDomainWrapper..ctor(AppDomain appDomain)
   in NLog.Internal.Fakeables.AppDomainWrapper.get_CurrentDomain()
   in NLog.Config.ConfigSectionHandler.System.Configuration.IConfigurationSectionHandler.Create(Object parent, Object configContext, XmlNode section)
   in System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   in System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   in System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   in System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)
   --- End of inner exception stack trace ---
   in System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
   in System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   in System.Configuration.ConfigurationManager.GetSection(String sectionName)
   in NLog.Config.XmlLoggingConfiguration.get_AppConfig()
   in NLog.LogFactory.get_Configuration()
   in NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
   in NLog.LogFactory.GetLogger(String name)
   in NLog.LogManager.GetCurrentClassLogger()

Update (config file)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="Test.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
      <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    </configSections>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets>
      <target name="logfile" xsi:type="File" fileName="log-${machinename}.txt" layout="${longdate} ${level:uppercase=True} ${logger} ${message} ${exception:format=ToString,StackTrace}" />
    </targets>
    <rules>
      <logger name="*" minlevel="Debug" writeTo="logfile" />
    </rules>
  </nlog>
    <applicationSettings>
    <Test.Properties.Settings>
        <setting name="servers" serializeAs="Xml">
            <value>
                <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <string>111</string>
                    <string>222</string>
                </ArrayOfString>
            </value>
        </setting>
    </Test.Properties.Settings>
    </applicationSettings>
</configuration>

NLog is instantiated this way (static field on a class):

private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
Was it helpful?

Solution

SOLUTION is to remove "untrusted origin" flag from application .config file using "unblock" button in file properties, or Sysinternals Streams tool

Thanks to @giammin who pointed me in right direction (trust level)!

Stupid me. It turns out that the cause of the problem was pretty obvious: it was result of Attachment Manager work. "Untrusted origin" flag (Zone.Identifier alternate data stream) was set on downloaded archive which contained app files.

What was unexpected for me in this, is that:

  1. I thought that only IE implements this "protective measure". Turns out, I was wrong - user downloaded the file via Chrome, which also sets this flag. Firefox doesn't set it (I checked on the latest versions to date).
  2. Flag was copied to files from archive (zip) after extraction. This happened, I believe, because user extracted files using built-in Windows archive tool.
  3. The direct cause of this problem was not a flag on assembly or executable files, but rather a flag on .config file itself. Once it was removed, problem disappeared. Flags on .exe/.dll files do not contribute to the problem in any way.
  4. I'm still not sure why this only happens on .net 4.0, and disappears when .net 4.5 is installed (application files are exactly the same).

OTHER TIPS

to debug nlog you can use its internal logging:

<nlog autoReload="true" throwExceptions="true" internalLogFile="c:\log.txt" internalLogLevel="Trace">

---UPDATE---

Another check could be to move the config to an external file:

<configSections>
    ...
  <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog configSource="NLog.config" />

NLog.config:

<?xml version="1.0"?>
<nlog autoReload="true" throwExceptions="true" internalLogFile="c:\log.txt" internalLogLevel="Trace">
...
</nlog>

Anyway It seems that the application is not running in FullTrust.

----UPDATE2----

Try to add this requirePermission="false" in

 <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" requirePermission="false"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top