Converting C# to PowerShell
Tom recently ran into a problem with the Connect-WebService script given here – when run against a server that returns malformed headers, he received the error message, “The server committed a protocol violation.”
The .NET Framework takes this approach as a security precaution, since parsing non-standard headers is one of the most common sources of vulnerabilities. It’s not that the header-parsing code has vulnerabilities (it may or may not, I have no inside knowledge,) but it is an absolute fact that you increase your risk as you expose more code to malicious input.
If you connect to a malicious server without this safeguard, then, you run an increased risk that the server might use malformed headers to exploit problems in the code intended to deal with it.
If you trust the server, then you might want work with it in all of its malformed-header glory, anyways. According to Tom’s research on the Internet, though, the only way to programmatically do this is through an internal property on the System.Net.Configuration.SettingsSection class.
The accepted solution from the MSDN Forum looks like this:
public static bool SetAllowUnsafeHeaderParsing20()
{
//Get the assembly that contains the internal class
Assembly aNetAssembly = Assembly.GetAssembly(
typeof(System.Net.Configuration.SettingsSection));
if (aNetAssembly != null)
{
//Use the assembly in order to get the internal type for the internal class
Type aSettingsType = aNetAssembly.GetType(
"System.Net.Configuration.SettingsSectionInternal");
if (aSettingsType != null)
{
//Use the internal static property to get an instance of the internal settings class.
//If the static instance isn't created allready the property will create it for us.
object anInstance = aSettingsType.InvokeMember("Section",
BindingFlags.Static | BindingFlags.GetProperty |
BindingFlags.NonPublic, null, null, new object[] { });
if (anInstance != null)
{
//Locate the private bool field that tells the framework is unsafe header parsing should be allowed or not
FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField(
"useUnsafeHeaderParsing", BindingFlags.NonPublic | BindingFlags.Instance);
if (aUseUnsafeHeaderParsing != null)
{
aUseUnsafeHeaderParsing.SetValue(anInstance, true);
return true;
}
}
}
}
return false;
}
Which translates cleanly to PowerShell as this:
$netAssembly = [Reflection.Assembly]::GetAssembly(
[System.Net.Configuration.SettingsSection])
if($netAssembly)
{
$bindingFlags = [Reflection.BindingFlags] "Static,GetProperty,NonPublic"
$settingsType = $netAssembly.GetType(
"System.Net.Configuration.SettingsSectionInternal")
$instance = $settingsType.InvokeMember("Section",
$bindingFlags, $null, $null, @())
if($instance)
{
$bindingFlags = "NonPublic","Instance"
$useUnsafeHeaderParsingField = $settingsType.GetField(
"useUnsafeHeaderParsing", $bindingFlags)
if($useUnsafeHeaderParsingField)
{
$useUnsafeHeaderParsingField.SetValue($instance, $true)
}
}
}