A System.Security.SecurityException is thrown when using the System.Net.HttpWebRequest class from a Windows Forms application based on .NET Framework 2.0 or 3.5 SP1
This article helps you resolve the System.Security.SecurityException
that's thrown when you use the System.Net.HttpWebRequest
class from a Windows Forms application based on Microsoft .NET Framework 3.5 SP1.
Original product version: Microsoft .NET Framework 3.5 Service Pack 1
Original KB number: 2512713
Symptoms
You're using the System.Net.HttpWebRequest
class from a Windows Forms application based on Microsoft .NET Framework 3.5 Service Pack 1 in a synchronous way. Specifically, this code is running on the main or UI thread. Your Windows Forms application throws an intermittent exception of type System.Security.SecurityException
that has a message similar to the following:
Request for the permission of type 'System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
The exception will show a faulting callstack similar to the following:
0:000> !clrstack
ESP EIP
<<ESP>> <<EIP>> System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
<<ESP>> <<EIP>> System.Threading.WaitHandle.WaitOne(Int64, Boolean)
<<ESP>> <<EIP>> System.Threading.WaitHandle.WaitOne(Int32, Boolean)
<<ESP>> <<EIP>> System.Net.NetworkAddressChangePolled.CheckAndReset()
<<ESP>> <<EIP>> System.Net.NclUtilities.get_LocalAddresses()
<<ESP>> <<EIP>> System.Net.WebProxyScriptHelper.myIpAddress()
.........
.........
<<ESP>> <<EIP>> System.Net.WebProxyScriptHelper+MyMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.CallOneOfTheMembers(System.Reflection.MemberInfo[], System.Object[], Boolean, System.Object, System.Reflection.Binder, System.Globalization.CultureInfo, System.String[], Microsoft.JScript.Vsa.VsaEngine, Boolean ByRef)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.Call(System.Reflection.Binder, System.Object[], System.Reflection.ParameterModifier[], System.Globalization.CultureInfo, System.String[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.Call(System.Object[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine).........
.........
<<ESP>> <<EIP>> Microsoft.JScript.JSMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.FunctionObject.Call(System.Object[], System.Object, Microsoft.JScript.ScriptObject, Microsoft.JScript.Closure, System.Reflection.Binder, System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.Closure.Call(System.Object[], System.Object, System.Reflection.Binder, System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.CallValue(System.Object, System.Object[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine, System.Object, System.Reflection.Binder, System.Globalization.CultureInfo, System.String[])
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.CallValue(System.Object, System.Object, System.Object[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine)
.........
.........
<<ESP>> <<EIP>> System.Reflection.MethodBase.Invoke(System.Object, System.Object[])
<<ESP>> <<EIP>> System.Net.VsaWebProxyScript.CallMethod(System.Object, System.String, System.Object[])
<<ESP>> <<EIP>> System.Net.VsaWebProxyScript.Run(System.String, System.String)
.........
.........
<<ESP>> <<EIP>> System.Net.IWebProxyScript.Run(System.String, System.String)
<<ESP>> <<EIP>> System.Net.AutoWebProxyScriptEngine.GetProxies(System.Uri, Boolean, System.Net.AutoWebProxyState ByRef, Int32 ByRef)
<<ESP>> <<EIP>> System.Net.WebProxy.GetProxiesAuto(System.Uri, System.Net.AutoWebProxyState ByRef, Int32 ByRef)
<<ESP>> <<EIP>> System.Net.ProxyScriptChain.GetNextProxy(System.Uri ByRef)
<<ESP>> <<EIP>> System.Net.ProxyChain+ProxyEnumerator.MoveNext()
<<ESP>> <<EIP>> System.Net.ServicePointManager.FindServicePoint(System.Uri, System.Net.IWebProxy, System.Net.ProxyChain ByRef, System.Net.HttpAbortDelegate ByRef, Int32 ByRef)
<<ESP>> <<EIP>> System.Net.HttpWebRequest.FindServicePoint(Boolean)
<<ESP>> <<EIP>> System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef)
<<ESP>> <<EIP>> System.Net.HttpWebRequest.GetRequestStream().........
.........
<<ESP>> <<EIP>> YourApplicationFunction.....
.........
.........
Cause
When the System.Net.HttpWebRequest
class is run from the main thread, which is also the User Interface (UI) thread, it may need to run the WPAD (Web Proxy Automatic Detection) protocol to detect whether a proxy is required for reaching the destination URL. During this process, System.Net
downloads and compiles the PAC (Proxy Auto-Configuration) script in memory and tries to execute the FindProxyForURL
function as per the PAC specification.
When doing so, System.Net
creates an internal application domain inside the application that runs with minimal permissions and most importantly, it doesn't grant the UI permission to this new application domain. The evaluation of a proxy and running the FindProxyForURL
JavaScript function happens in the context of this new application domain and during this process System.Net
may need to run several helper functions as per the PAC specification such as isInNet
, dnsResolve
, myIpAddress
to compute the proxy.
For example, when running the myIpAddress
function System.Net
will try to evaluate the current IP Address of the current machine and at some point it may have to use the System.Threading.WaitHandle.WaitOne()
function call. When this System.Threading.WaitHandle.WaitOne()
function is called from the main or UI thread, this call will keep processing window messages while it's waiting.
If the window message gets processed during the WaitOne()
call, the .NET framework Common Language Runtime (CLR) will make a full stack check and demand the UI permission. If it finds any mismatch in the permissions, a System.Security.SecurityException
is thrown.
Resolution
This behavior is by design.
To work around this issue, you can either switch to using the System.Net.HttpWebRequest
class asynchronously or you can still use the synchronous approach, but run it from a background thread or a non-UI thread. That way the window process will have free reign of the UI thread without having to interrupt wait calls in a different application domain.
Another approach that you can use is to keep the same code as before, but instead of having System.Net
run the automatic proxy detection on the main thread, you can create a new thread and try running the System.Net.WebProxy.GetProxy
function on this background thread and let the background thread perform the automatic Proxy detection. Once the background thread retrieves the address of a proxy server, you can set the Proxy
property of the HttpWebRequest
object, and set it to a fixed proxy. This will prevent the automatic proxy detection on the main thread and will not throw the exception.
If your environment has a fixed proxy configured, you can turn off the automatic proxy detection completely, by adding the following configuration settings in your application configuration file:
<system.net>
<defaultProxy>
<proxy autoDetect="False" usesystemdefault="False" proxyaddress="http://yourProxy:yourProxyPort"/>
</defaultProxy>
</system.net>
Note
Although running synchronous HTTP requests using the System.Net.HttpWebRequest
class should work fine in most scenarios, we don't recommend running synchronous network operations such as sending HTTP requests from the main or UI thread due to possible delays encountered during network operations (such as IP Address or DNS resolution, Proxy detection etc). It is best to run such synchronous requests from a background thread or run the requests asynchronously.
More information
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for