Security for Microsoft Visual Basic .NET

The safest bet is to assume you can’t detect and handle every unexpected circumstance and that exceptions will inevitably occur. When an exception occurs, you should follow a standard series of steps—basic do’s and don’ts—to handle the exception. Here is what your system should and shouldn’t do when designing your application to cope with exceptions:

The reason these are flawed error messages is that they divulge too much information about the inner workings of the system. The first example informs the intruder he has entered a valid username and invites him to try other passwords until he gets it right. The second example tells the intruder the precise location of the database the system is using—if he can gain access to the network, the intruder now knows where to look to find your application’s database. The third flawed message reveals the contents of the SQL statement, which in some cases will allow the intruder to adjust his input to twist the SQL statement to some nefarious purpose. You should never expose the inner workings of the system to the end user. For an intruder intent on breaking in, doing so might give away vital information about the system. A good practice is to never directly echo back to the user the information that Visual Basic .NET gives the application about the error. Usually this information is irrelevant to anyone but the application’s developer. Instead, your application should give a message in terminology the user will understand.

Add exception handling to the employee management system

In this exercise, you will add a procedure to SecurityLibrary.vb that logs details about an exception to the event log. You will then add exception handling to the employee management system clsEmployee class to catch exceptions when retrieving information from the database.

  1. In Microsoft Visual Basic .NET, open the solution CH08_ErrorHandling\EMS\Start\EMS.sln.

  2. Before adding the exception-handling code, let’s create an exception case. Open MainModule.vb, and change the line of code that sets the database name from

    Const DatabaseName As String = "EmployeeDatabase.mdb"

    to

    Const DatabaseName As String = "Invalid.mdb"

  3. Now press F5 to run the employee management system. When you try to log in, you will see an exception dialog box that should look something like this:

Interestingly, the exception dialog box changes when the application is run outside of the Visual Basic .NET debugger. What your users would see in that case is shown here:

This unhandled exception gives too much information about what went wrong.

  1. Open SecurityLibrary.vb, and add the following code to the end of the module. This code logs an exception to the Windows event log. If the version of Windows is Windows 98 or Windows ME, the exception is added to a file in the Application Data directory.

    Namespace EventLog Module EventLog Sub LogException(ByVal ex As Exception) ’If this is an NT based operating system ‘(Windows NT4, Windows2000, ’Windows XP, Windows Server 2003) ‘then add the exception to the ’application event log. ’If the operating system is Windows98 or WindowsME, then ’append it to a <appname>.log file in the ‘ApplicationData directory Dim strApplicationName As String Dim blnIsWin9X As Boolean Dim FileNumber As Integer = -1 Try ’Get name of assembly strApplicationName = _ System.Reflection.Assembly.GetExecutingAssembly.GetName.Name blnIsWin9X = (System.Environment.OSVersion.Platform <> _ PlatformID.Win32NT) If blnIsWin9X Then ’Windows98 or WindowsME Dim strTargetDirectory, strTargetPath As String ’Get Application Data directory, and create path strTargetDirectory = System.Environment.GetFolderPath( _ Environment.SpecialFolder.ApplicationData) strTargetPath = strTargetDirectory & "\" & _ strApplicationName & ".Log" ’Append to the end of the log (or create a new one ’if it doesn’t already exist) FileNumber = FreeFile() FileOpen(FileNumber, strTargetPath, OpenMode.Append) PrintLine(FileNumber, Now) PrintLine(FileNumber, ex.ToString) FileClose(FileNumber) Else ’WinNT4, Win2K, WinXP, Windows.NET System.Diagnostics.EventLog.WriteEntry(_ strApplicationName, _ ex.ToString, _ EventLogEntryType.Error) End If Finally If FileNumber > -1 Then FileClose(FileNumber) End Try End Sub End ModuleEnd Namespace

  2. Open the class clsEmployee.cls, and locate the Create function. This function takes a username, retrieves the profile data from the database, and stores it in the class. Add a Try…Catch exception handler to make the code look like the following:

    Public Shared Function Create(ByVal strUserName As String) _ As clsEmployee Dim employee As clsEmployee Try employee = New clsEmployee() 'Avoid a SQL injection attack: Insure username contains no 'dangerous symbols such as apostrophes or dashes (SQL comment) If Not ValidateInput.IsValidUserName(strUserName) Then employee.m_IsValidUser = False Return employee End If 'Avoid a SQL injection attack: Use a parameterized query to load 'information from the employee table Dim strSQL As String = _ "Select * from Employee where Username = " & _ "@ParameterUserName" Dim cn As OleDbConnection Dim cmd As OleDbCommand Dim dr As OleDbDataReader cn = New OleDbConnection(G_CONNECTIONSTRING) cmd = New OleDbCommand(strSQL, cn) cmd.CommandType = CommandType.Text cmd.Parameters.Add("@ParameterUserName", strUserName) cn.Open() dr = cmd.ExecuteReader() If dr.Read() Then employee = New clsEmployee() employee.FirstName = CStr(dr("FirstName")) employee.LastName = CStr(dr("LastName")) employee.FullName = CStr(dr("Fullname")) employee.m_PasswordHash = CStr(dr("PasswordHash")) employee.m_BankAccountEncrypted = _ CStr(dr("BankAccountEncrypted")) employee.m_Username = strUserName employee.m_IsValidUser = True End If 'Obtain the list of roles associated with the user and assigns 'the principal--containing the user and roles--to the ‘current thread. SetPrincipalPolicy(employee.m_Username) Catch ex As Exception 'If an exception occurs, the ex variable is created 'and will hold an object with all the exception information EventLog.LogException(ex) employee.m_IsValidUser = False End Try Return employeeEnd Function

  3. Now press F5 to run the application, and attempt to log in. Instead of receiving an ugly exception, your users are told, “Could not log in. Please try again.” The exception information is saved to the application event log. You can view the application event log by choosing Run from the Start menu, typing EventVwr.exe, and pressing Enter. In the application event log, you will see an entry for the exception you just logged, as shown here:

  4. Before continuing, change the database path back to its correct setting. Open MainModule.vb, and change the line of code that sets the database name from

    Const DatabaseName As String = "Invalid.mdb"

    to

    Const DatabaseName As String = "EmployeeDatabase.mdb"

Try…Catch or On Error GoTo

Visual Basic .Net supports two forms of exception handling: Try…Catch exception handling (as used in the previous example) and the older style On Error GoTo exception handling. You might be wondering, “Which should I use?” There is no definitive answer. Which method you choose is mainly a matter of personal preference, although Try…Catch exception handling has an edge over On Error GoTo for several reasons. Try…Catch exception handling offers a finer degree of tuning because you can nest Try…Catch exception blocks within other Try…Catch exception blocks. Also, you can add several Catch clauses to handle different types of exceptions and a Finally clause to run code at the end of processing whether an exception occurred or not. The following code snippet shows the syntax for targeted exception handling and code that runs in a Finally clause:

Try ’Some codeCatch exFileNotFound As System.IO.FileNotFoundException ’Exception handler for file not foundCatch ex As Exception ’Exception handler for all other types of exceptionsFinally ’Code that always runs at the end of processingEnd Try

Try…Catch exception handling also results in slightly cleaner compiled code, although the effects of this are negligible. You can mix and match the two types of exception handling, using On Error GoTo in one function and Try…Catch in another. However, the Visual Basic compiler will not let you use both On Error GoTo and Try…Catch in the same function.

Категории