"Application Crash via Voucher Code Containing non-ASCII Characters"

From IncludeSec's 2021 Q2 security audit report (pp. 14-15; "informational finding 2"):

I2: Gridsync Application Crash via Voucher Code Containing non-ASCII Characters

Description:
The assessment team was able to crash the Gridsync application by entering a voucher code containing non-ASCII characters.

Impact:
An attacker could leverage this by sending or posting an voucher code with non-ASCII characters and tricking a targeted user into entering it into the application. This could interrupt application actions such as uploading and downloading files to and from the storage grid.

Reproduction:

  1. Launch the Gridsync application from the command line with the —debug flag.
  2. Join the HRO Cloud Grid, which requires entry of a voucher once joined.
  3. Tap Use voucher code.
  4. Enter a voucher containing non-ASCII characters.
  5. Observe that the application crashes.

The crash occurred in the is_valid() function of the voucher.py module, on line 39 when the voucher was decoded:

def is_valid(code: str, checksum_length: int = 2) -> bool:
   code = dehyphenate(code)
   try:
       decoded = base64.b32decode(code)
   except binascii.Error:
       return False
   b = decoded[:-checksum_length]
   checksum = decoded[-checksum_length:]
   if checksum == get_checksum(b):
       return True
   return False

The except statement is executed and returns false when an invalid base-32 ASCII character is found. However processing a non-ASCII character crashed the application:

Traceback (most recent call last):
  File "base64.py", line 37, in _bytes_from_decode_data
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-15: ordinal not in range(128)

During handling of the above exception, another exception occurred. An example voucher that will cause a crash and display the following output from the --debug option is *AAAA-AAAA-AAAA-AAAŁ*

Traceback (most recent call last):
  File "gridsync/gui/voucher.py", line 52, in on_return_pressed
  File "gridsync/voucher.py", line 39, in is_valid
  File "base64.py", line 203, in b32decode
  File "base64.py", line 39, in _bytes_from_decode_data
ValueError: string argument should contain only ASCII characters
Abort trap: 6

Recommended Remediation:
The assessment team recommends adding additional exception handling to detect and gracefully handle invalid voucher codes.