Securing your application against malicious attacks is not an easy task. It is the constant struggle between writing secure code while minimizing bugs (which hackers usually exploit) and black hats writing more and more sophisticated methods to compromise systems and networks. I personally believe that higher learning institutions need to teach IT students two things:
In fact, I believe that secure programming 101 must not simply be a module or topic in a given IT course, but a whole course on its own. It needs to be handled with the seriousness and respect it deserves and needs to preferably be taught by someone that can actually hack a system or network.
White hats teaching students how to compromise systems, exploit vulnerable code, and infiltrate networks will make a big difference in changing the way future software developers approach programming. It comes down to developers knowing what not to do when programming defensively. It is quite possible that some of those students might go on to become black hats themselves, but they would have done that irrespective of whether they took a class on hacking secure programming or not.
The code might look a little funny in some places. This is because SecureString
is using unmanaged memory to store the sensitive information. Rest assured that SecureString
is well supported and used within the .NET Framework, as can be seen from the instantiation of the SqlCredential
object used in creating connections to a database:
winformSecure
and click on the OK button:The code that is created for you is the KeyPress event handler for the text box control. This will fire whenever a user presses a key on the keyboard:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { }
true
:using
statement:using System.Runtime.InteropServices;
SecureString
variable as a global variable to your Windows Forms:SecureString secure = new SecureString();
KeyPress
event, append the KeyChar
value to the SecureString
variable every time the user presses a key. You might want to add code to ignore certain key presses, but this is beyond the scope of this recipe:private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { secure.AppendChar(e.KeyChar); }
SecureString
object. Here we are working with unmanaged memory and unmanaged code:private void btnLogin_Click(object sender, EventArgs e) { IntPtr unmanagedPtr = IntPtr.Zero; try { if (secure == null) throw new ArgumentNullException("Password not defined"); unmanagedPtr = Marshal.SecureStringToGlobalAllocUnicode(secure); MessageBox.Show($"SecureString password to validate is {Marshal.PtrToStringUni(unmanagedPtr)}"); } catch(Exception ex) { MessageBox.Show(ex.Message); } finally { Marshal.ZeroFreeGlobalAllocUnicode(unmanagedPtr); secure.Dispose(); } }
It has become almost a habit for many developers to use System.String
to store sensitive information such as passwords. The problem with this approach is that System.String
is immutable. This means that the object created in memory by System.String
can't be changed. If you modify the variable, a new object is created in memory. You also cannot determine when the object created by System.String
will be removed from memory during garbage collection. Conversely, by using the SecureString
object, you will encrypt sensitive information and when that object is no longer needed, it is deleted from memory. SecureString
encrypts and decrypts your sensitive data in unmanaged memory.
Now I need to be clear regarding one thing here. SecureString
is by no means foolproof. If your system contains a virus with the sole purpose of compromising the SecureString
operations, using it doesn't help much (be sure to use proper anti-virus software anyway). At some point during the code execution, the string representation of your password (or sensitive information) is visible. Secondly, if a hacker somehow found a way to inspect your heap or log your key strokes, the password might be visible. The use of SecureString
, however makes this window of opportunity for a hacker much smaller. The window of opportunity reduces because there are less attack vectors (points of entry for a hacker), thereby reducing your attack surface (sum of all points of attack by a hacker).
The bottom line is this: SecureString
is there for a reason. As a software developer concerned about security, you should be using SecureString
.