Negative digits in otpauth:// URI causes ArithmeticException crash
Summary
An otpauth:// URI with a negative digits parameter causes Aegis to crash with an
uncaught ArithmeticException (integer modulo by zero) when the app tries to generate
the code for that entry. The digits value is read from the URI and stored without any
range validation.
Steps to reproduce
- Create / share a QR code (or send an
otpauth://intent) containing a negativedigitsvalue, e.g.:otpauth://totp/Test:acct?secret=JBSWY3DPEHPK3PXP&digits=-1 - In Aegis, scan the QR (or open the shared URI) and add the entry.
- The app crashes when it attempts to generate/display the code.
Expected
The entry is rejected (or digits is clamped to a valid range) — no crash.
Actual
Crash with ArithmeticException from OTP.java.
Root cause
In GoogleAuthInfo.parseUri() (file app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java),
the digits query parameter is parsed and passed through with no range check:
String digits = uri.getQueryParameter("digits");
if (digits != null) {
info.setDigits(Integer.parseInt(digits)); // no validation
} setDigits() stores the value. Later, when the code is generated, OTP computes:
int code = _code % (int) Math.pow(10, _digits); For _digits < 0, (int) Math.pow(10, _digits) evaluates to 0 (e.g.
(int) Math.pow(10, -1) == 0), so the expression becomes code % 0 →
ArithmeticException: / by zero, which is uncaught and crashes the app.
Suggested fix
Validate digits (and, for consistency, period/counter) in GoogleAuthInfo.parseUri
before setting them — e.g. reject or clamp non-positive / out-of-range values, and
whitelist the algorithm. Something like:
String digits = uri.getQueryParameter("digits");
if (digits != null) {
int d = Integer.parseInt(digits);
if (d < 1 || d > 10) { // sane bounds for OTP digit counts
throw new GoogleAuthInfoException(uri, "Invalid digits: " + digits);
}
info.setDigits(d);
} Notes
- Severity: low — it's a local DoS (app crash); the user has to scan/import a
malicious entry themselves. No data loss (the vault is intact; reopening the app is fine
once the bad entry is removed). - While reviewing, I noticed
period,counter, andalgorithmare likewise read from
the URI without validation.period = 0doesn't crash (it's floating-point division inTOTP.generateOTP), but a co
Source: beemdevelopment/Aegis