Code Samples for Businesses, Schools & Developers

Page 1 Page 2

First Published 4 Nov 2023                         Last Updated 29 Apr 2024


The first two articles in this series provided automation code to open databases using the shift key to bypass startup code.

However, the code will not work if the AllowBypassKey property of the database has been disabled.
This is often done as a security measure to ensure required startup code is always run.

The AllowBypassKey property does not exist by default. Before it can be disabled (or enabled), the property must first be created.

The code to do this for the current database is shown below. It should be placed in a standard module

CODE:

Option Compare Database
Option Explicit

Dim db As DAO.Database
Dim prop As DAO.Property
Const conPropNotFound = 3270

' ======================================

Function DisableShiftBypass()

'This function disables the shift at startup. This action causes
'the Autoexec macro and Startup properties to always be executed.

On Error GoTo Err_Handler

      Set db = CurrentDb()

      'This next line disables the shift key on startup.
      db.Properties("AllowByPassKey") = False

Exit_Handler:
      Exit Function

Err_Handler:
      'The first part of this error routine creates the "AllowByPassKey property if it does not exist.
      If Err = conPropNotFound Then
            Set prop = db.CreateProperty("AllowByPassKey", dbBoolean, False)
            db.Properties.Append prop
            Resume Next
      Else
            MsgBox "Error " & Err & " " & Err.Description, vbExclamation, "DisableShiftBpass did not complete successfully."
            Resume Exit_Handler
      End If

End Function

' ======================================

Function EnableShiftBypass()

'This function enables the SHIFT key at startup. This action causes
'the Autoexec macro and the Startup properties to be bypassed
'if the user holds down the SHIFT key when the user opens the database.

On Error GoTo Err_Handler

      Set db = CurrentDb()

      'This next line of code enables the use of the SHIFT key on startup.
      db.Properties("AllowByPassKey") = True

Exit_Handler:
      Exit Function

Err_Handler:
      'The first part of this error routine creates the "AllowByPassKey property if it does not exist.
      If Err = conPropNotFound Then
            Set prop = db.CreateProperty("AllowByPassKey", dbBoolean, True)
            db.Properties.Append prop
            Resume Next
      Else
            MsgBox "Error " & Err & " " & Err.Description, vbExclamation, "EnableShiftBpass did not complete successfully."
            Resume Exit_Handler
      End If

End Function


Unfortunately, it is also possible to do each of these from an external database using automation code.
This does make your databases more vulnerable to hacking.

As the code to do this is already widely available on the internet, I am providing it below.
However, later in this article I will also show how you can mitigate the effects of this in your own databases

The following code allows you to check the AllowByPassKey value and to enable or disable it from an external database. Place it in a standard module.

CODE:

Option Compare Database
Option Explicit

Dim db As DAO.Database
Dim prop As DAO.Property
Const conPropNotFound = 3270

' ======================================

Function CheckBypassValue(strPath As String, Optional strPwd As String) As Boolean

On Error GoTo Err_Handler

      If strPwd <> "" Then
           Set db = DBEngine.OpenDatabase(strPath, True, False, "MS Access;PWD=" & strPwd)
      Else
           Set db = DBEngine.OpenDatabase(strPath, True, False)
      End If

      'Get the value of the specified property
      CheckBypassValue = db.Properties("AllowByPassKey")

     If CheckBypassValue Then
           MsgBox "Shift bypass enabled", vbInformation, strPath
     Else
            MsgBox "Shift bypass disabled", vbInformation, strPath
      End If

Exit_Handler:
      Exit Function

Err_Handler:
      'err 3270 'The property was not found
      If Err.Number = 3270 Then
            MsgBox "Shift bypass property does not exist", vbInformation, strPath
      Else
            MsgBox "Error " & Err.Number & " in CheckBypassValue procedure: " & vbCrLf & "Description: " & Err.Description
      End If

      Resume Exit_Handler

End Function

' ======================================

Sub DisableShiftBypassExtDB(strPath As String, Optional strPwd As String)

'This function disables the shift at startup.
'This action causes the Autoexec macro and Startup properties to always be executed.

On Error GoTo Err_Handler

      If strPwd <> "" Then
            Set db = DBEngine.OpenDatabase(strPath, True, False, "MS Access;PWD=" & strPwd)
      Else
            Set db = DBEngine.OpenDatabase(strPath, True, False)
      End If

      db.Properties("AllowByPassKey") = False
      db.Close
      Set db = Nothing

Exit_Handler:
      Exit Sub

Err_Handler:
      'The first part of this error routine creates the "AllowByPassKey property if it does not exist . . . and sets it false.
      If Err = conPropNotFound Then
            'err 3270
            Set prop = db.CreateProperty("AllowByPassKey", dbBoolean, False)
            db.Properties.Append prop
            Resume Next
      Else
            'err 3031 - not a valid password
            MsgBox "Error " & Err & " " & Err.Description, vbExclamation, "DisableShiftBpassExtDB did not complete successfully."
            Resume Exit_Handler
      End If

End Sub

' ======================================

Sub EnableShiftBypassExtDB(strPath As String, Optional strPwd As String)

'This function enables the shift bypass at startup.
'This action allows the Autoexec macro and Startup properties to be bypassed

On Error GoTo Err_Handler

      If strPwd <> "" Then
            Set db = DBEngine.OpenDatabase(strPath, True, False, "MS Access;PWD=" & strPwd)
      Else
            Set db = DBEngine.OpenDatabase(strPath, True, False)
      End If

      db.Properties("AllowByPassKey") = True
      db.Close
      Set db = Nothing

Exit_Handler:
      Exit Sub

Err_Handler:
      'The first part of this error routine creates the "AllowByPassKey property if it does not exist . . . and sets it true.
      If Err = conPropNotFound Then
            'err 3270
            Set prop = db.CreateProperty("AllowByPassKey", dbBoolean, True)
            db.Properties.Append prop
            Resume Next
      Else
            'err 3031 - not a valid password
            MsgBox "Error " & Err & " " & Err.Description, vbExclamation, "EnableShiftBpassExtDB did not complete successfully."
            Resume Exit_Handler
      End If

End Sub


The example app also includes an OpenWithShiftBypass procedure. This will only work if the shift bypass is first disabled e.g. using the code above

The code has been provided to assist users manage their own databases.
It should NOT be used to modify or hack any external database without permission.

Option Compare Database
Option Explicit
Option Private Module

#If VBA7 Then
      Declare PtrSafe Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
#Else
      Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
#End If

#If VBA7 Then
      Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
#Else
      Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
#End If

'=======================================================================

Sub OpenWithShiftBypass(strPath As String, Optional blnExcl As Boolean = False, Optional strPwd As String)

Dim appAccess As Access.Application

On Error GoTo Err_Handler

      'OPTIONAL - browse to your database, check shift bypass state and enable it if necessary
      'EnableShiftBypassExtDB strPath

      ' Create a new instance of Access
      Set appAccess = New Access.Application

      ' Simulate pressing the Shift key
      keybd_event vbKeyShift, 0, 0, 0

      'OPTIONAL - enable next line to add short delay of 0.1 second here if your results aren't reliable
      ' Sleep 100

      ' Open the target database
      If strPwd <> "" Then
            appAccess.OpenCurrentDatabase strPath, blnExcl, strPwd
      Else
            appAccess.OpenCurrentDatabase strPath, blnExcl
      End If

      'OPTIONAL - make external app visible
      appAccess.Visible = True

      ' Simulate releasing the Shift key
      keybd_event vbKeyShift, 0, 2, 0

      'OPTIONAL - Wait 5 seconds so external app can be viewed before closing it
      Sleep 5000

      'OPTIONAL - Close the target database
      appAccess.CloseCurrentDatabase

      ' Quit the new instance of Access
      appAccess.Quit

      ' Release the object
      Set appAccess = Nothing

Exit_Handler:
      Exit Sub

Err_Handler:
      'err 2467 = The expression you entered refers to an object that is closed or doesn't exist.
      'occurs if user closed external database manually before above code runs
      If Err = 2467 Then Resume Next

      MsgBox "Error " & Err.Number & " in line " & Erl & " of OpenWithShiftBypass procedure : " & _
            Err.Description, vbOKOnly + vbCritical, "Critical Error"

      keybd_event vbKeyShift, 0, 2, 0 'release the Shift key
      Resume Exit_Handler

End Sub



UPDATE 29 Apr 2024
I have added the OPTIONAL line Sleep 100 in the OpenWithShiftBypass procedure above following feedback from Greg Sevior.
He reported getting inconsistent results on a fast SSD drive running Access 2016. Adding a short delay of 0.1 second fixed the issue for him.

You should enable the line if necessary on your own test workstations.



Example usage:
a)   Database with no password
      CheckBypassValue "G:\MyFiles\ExampleDatabases\Northwind\2023\Northwind22Dev.accdb"

      DisableShiftBypassExtDB "G:\MyFiles\ExampleDatabases\Northwind\2023\Northwind22Dev.accdb"

      OpenWithShiftBypass "G:\MyFiles\ExampleDatabases\Northwind\2023\Northwind22Dev.accdb"

b)   Database encrypted with password: isladogs
      CheckBypassValue "G:\MyFiles\ExampleDatabases\ShiftBypass\TestDBPwd.accdb", "isladogs"

      EnableShiftBypassExtDB "G:\MyFiles\ExampleDatabases\ShiftBypass\TestDBPwd.accdb", "isladogs"

      OpenWithShiftBypass "G:\MyFiles\ExampleDatabases\ShiftBypass\TestDBPwd.accdb", "isladogs"

CheckBypassValue



Click to download:

The zip file contains an example database BypassCode with all the above code in module modShiftBypass.
It also includes with two test databases TestDb and TestDBPwd. The password for the encrypted database is isladogs

      Bypass Test Databases      (ACCDB - zipped)

Download the zip file and unblock it.
For more details, see my article: Unblock downloaded files by removing the Mark of the Web

Unzip and save the ACCDB files to a trusted location.

The 2 test databases each have a startup form which is colour coded according to the AllowBypassKey value:

BypassKey does not exist

BypassKey does not exist
AllowBypassKey Enabled

Shift Bypass Enabled
AllowBypassKey Disabled

Shift Bypass Disabled



Further Information

The shift bypass is a very useful tool for developers to open databases without any startup code running.
For example, it is useful as a diagnostic tool if errors occur when an application is loaded.

Nevertheless when a database is deployed, most developers will want to ensure that startup code does run.
To do so, disable the shift bypass by setting the AllowByPassKey value to False.

However, the code above shows that it is also possible for other users to re-enable the shift bypass and undo some of the database security.

It is almost impossible to prevent being done to an Access database.

For that reason, you should not rely on the use of the shift bypass as the only method of securing your database.
For further information on other methods of adding security, see my article: Securing Your Database - A Tutorial

By following the suggestions in that article, you can make it much harder for users to bypass your security

The ShiftBypassQuit example database below uses several of those methods to limit the effects of bypassing security.
It is supplied as a 32-bit or 64-bit ACCDE with password isladogs

When the database is opened normally, the startup form frmStart appears 'floating on the desktop' with the Access application interface hidden.

Bypass Quit DEMO

Click the Enable Shift Bypass button and restart the application normally. Do NOT press the Shift key at this stage.
As the application loads, the Shift Bypass is automatically DISABLED again

Click the Enable Shift Bypass button and restart the application again. This time, press the Shift key as you enter the password.
The startup code is bypassed and the startup form does not load.

However, the navigation pane is empty as all database objects have been hidden.

Shift Bypass Used

Check Show Hidden Objects in Navigation Options to view the database objects

Show Hidden Objects

Click form frmAutomation. This opens but is hidden. It immediately disables the ShiftBypass again and form frmStart appears.
Once again the application interface is automatically hidden.

Repeat the previous steps but this time click frmStart in the navigation pane. The form does NOT open.
In fact, nothing seems to happen!
See my article Prevent Opening Objects From the Navigation Pane for an explanation of how this is done.

However, it is also possible to open forms from the Visual Basic Editor (VBE). As this is an ACCDE file, you cannot view the code.
Instead, type the following in the VBE Immediate pane:

Immediate Pane

When you press Enter, this message appears:

Immediate Pane Error

Click OK and the database closes.

Normally, I would recommend reapplying the shift bypass at startup but, for the purpose of this demo I have deliberately not done so.

Also try opening the app from a non trusted location and note what happens.

/Error 2501

In summary, I have not prevented you re-enabling the shift bypass but if you do so, other code will (hopefully) prevent you getting anywhere 'useful'.

NOTE:
The example app is not completely secure. I know of at least one method of circumventing the security.
There are additional things I could do to improve it further. However, its good enough to deter all but the most determined hackers.

Obviously, using an ACCDE file provides added protection but the example app is also fairly secure even as an ACCDB file.

If you like a challenge and are able to bypass the built-in security, please email me using the Feedback form and let me know how you did so!



Click to download:

Choose the correct bitness for your version of Access:
          Shift Bypass Quit 32      (32-bit ACCDE - zipped)
          Shift Bypass Quit 64      (64-bit ACCDE - zipped)

Download the zip file and unblock it. Unzip and save the ACCDE file to a trusted location.



Further Reading

These related articles may also be of interest:

      Securing Your Database - A Tutorial

      Encrypted Split No Strings Database

      Prevent Opening Objects From the Navigation Pane

      Protect Data in Tables and Queries

      Lock Down Database Objects



Feedback

Please use the contact form below to let me know whether you found this article interesting/useful or if you have any questions/comments.

Please also consider making a donation towards the costs of maintaining this website. Thank you



Colin Riddington           Mendip Data Systems                 Last Updated 29 Apr 2024



Return to Code Samples Page Page 3 of 3 1 2 3 Return To Top