Author:水如烟
由于反射的引入,.NET的变量在代码集中并不安全。必须重视和把好源代码的审核关。
.NET的安全性问题是一个综合性的问题,这不是我现在能学习好理解透的,我估计也不是一般的.NET的编码者能够把握住应用好的。
至少,在代码集中,.NET的全局变量,或者说受Private修饰保护的对象,是不安全的。
在现实中有一个传话游戏,其要义是,信息在信息链的传递过程中会失真。.NET也一样,很难保证一个关键的信息在传递的过程中保持“纯洁”而不被潜伏中的攻击而受污染。特别是在大规模的代码集中。
SecureString类
在.NET的设计中,SecureString类应该是安全系数比较高的。它有两个作用,一是赋值后MakeReadOnly以便在后续的传递中不致修改,二是在必要的时候进行销毁。但是用它来传递关键信息,比如密码,还是不安全的。这个类里头有一个m_readOnly As Boolean的Private变量来保存当前实例可否修改的状态,你可以重置该值为False,便可以对它重新修改,MakeReadOnly也就失去了它本身的作用。
ReadOnlyCollection类
它的本义是不能对当前实例的项目进行增删。在它的设计中,用一个list的Private变量来存储当前集合。事实并不能保证它的作用。你甚至可以用自己的list替换了它。
测试代码
Imports
System.Runtime.InteropServices
Imports System.Collections.ObjectModel
Public Class NoSecure
Public Sub TestSecureString()
Dim t As New Security.SecureString
t.AppendChar( " A " c)
t.AppendChar( " B " c)
t.MakeReadOnly()
Console.WriteLine(Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(t)))
Dim h As New LzmTW.uSystem.uReflection.TypeHelper(t)
h.SetMemberValue( " m_readOnly " , False )
t.AppendChar( " C " c)
Console.WriteLine(Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(t)))
End Sub
Public Sub TestReadonlyCollection()
Dim t As New ReadOnlyCollection(Of String )( New String () { " A " , " B " , " C " })
For i As Integer = 0 To t.Count - 1
Console.Write(t.Item(i))
Next
Console.WriteLine()
Dim h As New LzmTW.uSystem.uReflection.TypeHelper(t)
Dim mNowList As New List(Of String )
mNowList.AddRange( New String () { " A " , " B " , " C " , " D " })
h.SetMemberValue( " list " , mNowList)
For i As Integer = 0 To t.Count - 1
Console.Write(t.Item(i))
Next
End Sub
End Class
Imports System.Collections.ObjectModel
Public Class NoSecure
Public Sub TestSecureString()
Dim t As New Security.SecureString
t.AppendChar( " A " c)
t.AppendChar( " B " c)
t.MakeReadOnly()
Console.WriteLine(Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(t)))
Dim h As New LzmTW.uSystem.uReflection.TypeHelper(t)
h.SetMemberValue( " m_readOnly " , False )
t.AppendChar( " C " c)
Console.WriteLine(Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(t)))
End Sub
Public Sub TestReadonlyCollection()
Dim t As New ReadOnlyCollection(Of String )( New String () { " A " , " B " , " C " })
For i As Integer = 0 To t.Count - 1
Console.Write(t.Item(i))
Next
Console.WriteLine()
Dim h As New LzmTW.uSystem.uReflection.TypeHelper(t)
Dim mNowList As New List(Of String )
mNowList.AddRange( New String () { " A " , " B " , " C " , " D " })
h.SetMemberValue( " list " , mNowList)
For i As Integer = 0 To t.Count - 1
Console.Write(t.Item(i))
Next
End Sub
End Class