使用XMLSerialization的明文密码

时间:2017-05-10 11:41:14

标签: c# xml serialization asmx

我正在使用XML与第三方Web服务进行通信。一切正常,但我们的安全扫描程序报告了一些CWE-216缺陷。

密码确实存储在类似于下面的LoginDetails类的内存中(为简单起见,简化)

[Serializable()]
public class LoginDetails
{
    public string Login { get; set; }
    public string Password { get; set; }
}

第三方要求以明文形式发送密码。所以不幸的是我在这里没有选择。我想要做的是确保字段在使用时尽快安全存储和/或从内存中删除。

在补救方面,我尝试使用SecureString - 显而易见的原因 - 并使用StringBuilder因为这会抵消不变性。我还尝试在IDisposable课程上实施LoginDetails。这包括将两个属性设置为null。然后我开始进行各种讨论(particularly this one),说它并没有太大的好处。

问题是,将Password字段类型更改为SecureStringStringBuilder时 - 它们未正确序列化 - 因此请求在第三方失败。有没有什么方法可以覆盖XMLSerializer以不同的方式处理这些类型 - 所以它们在我们这方面更安全地存储在内存中,但是以明文形式传送给第三方 - 或者整个尝试是无意义的基于这些安全尝试不会在双方实施?

或者有什么我完全忽略了吗?

非常感谢

1 个答案:

答案 0 :(得分:0)

为了解决这个问题,我创建了一个名为SerializableSecureString的自定义类型,同时实现IXmlSerializableIDisposable

希望以后可以帮助某人出去!

<强>实施

该类型包含私有SecureString成员变量,以及用于序列化的私有string属性。

private readonly SecureString Content = new SecureString();
private string Value { }

私有字符串属性的get解包私有成员变量,如下所示...

get
{
    IntPtr bstr = Marshal.SecureStringToBSTR(Content);
    string copiedText = Marshal.PtrToStringAuto(bstr);
    Marshal.ZeroFreeBSTR(bstr);

    return copiedText;
}

有两个构造函数。一个空构造函数,仅由.Net用于序列化...

public SerializableSecureString()
{
}

...和另一个用于实际构造的类型。它需要一个明文字符串并将其打包到SecureString变量中,如此...

public SerializableSecureString(string clearText)
{
    if (clearText != null)
    {
        foreach (char t in clearText)
            Content.AppendChar(t);
    }
}

序列化发生在IXmlSerializable函数中WriteXml的实现中。它使用WriteString写出私有字符串属性(值)...

的值
public void WriteXml(XmlWriter writer)
{
    writer.WriteString(Value);
}

要处置SecureString值,我在Dispose模式中实现了IDisposable方法并调用了Content.Dispose()

<强>用法

我可以创建一个LoginDetails类的实例(在问题中引用),如下所示......

LoginDetails loginDetails = new LoginDetails
{
    Login = "MyUsername",
    Password = new SerializableSecureString(WebConfigurationManager.AppSettings["MyPassword"])
};

密码存储在web.config文件的加密部分中 - 因此使用WebConfigurationManager

使用后,数据可以放在finally块中,如下所示

finally
{
    LoginDetails.Password.Dispose();
}