Package: pass-otp
Version: 1.2.0-9
Severity: normal
Tags: security patch
Forwarded: https://github.com/tadfisher/pass-otp/issues/167 
https://github.com/tadfisher/pass-otp/pulls/182
X-Debbugs-Cc: Debian Security Team <[email protected]>

Since upstream seems to be undermaintained, could you add the attached
patches to the Debian package for slightly more oathtool safety?

The first one uses bash arrays to separate command-line arguments,
instead of fragile shell string splitting.

The second one passes OTP secrets to oathtool on stdin instead
of command-line arguments, when it is new enough to support that.

These have been backported from my pull request linked above
and resolve the upstream bug report linked above. 

-- 
bye,
pabs

https://wiki.debian.org/PaulWise
From 41c60cb5a128da006a8b474b58550a95aa4b33a8 Mon Sep 17 00:00:00 2001
From: Paul Wise <[email protected]>
Date: Fri, 12 May 2023 13:39:53 +0800
Subject: [PATCH 1/2] Use bash arrays to separate arguments to oathtool and
 otptool

Also use long version of oathtool -b/--base32 option.
---
 otp.bash | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/otp.bash b/otp.bash
index d4c7756..7702c07 100755
--- a/otp.bash
+++ b/otp.bash
@@ -334,18 +334,19 @@ cmd_otp_code() {
   local cmd
   case "$otp_type" in
     totp)
-      cmd="$OATH -b --totp"
-      [[ -n "$otp_algorithm" ]] && cmd+=$(echo "=${otp_algorithm}"|tr "[:upper:]" "[:lower:]")
-      [[ -n "$otp_period" ]] && cmd+=" --time-step-size=$otp_period"s
-      [[ -n "$otp_digits" ]] && cmd+=" --digits=$otp_digits"
-      cmd+=" $otp_secret"
+      cmd=("$OATH" --base32)
+      [[ -z "$otp_algorithm" ]] && cmd+=(--totp)
+      [[ -n "$otp_algorithm" ]] && cmd+=(--totp="$(echo "${otp_algorithm}"|tr "[:upper:]" "[:lower:]")")
+      [[ -n "$otp_period" ]] && cmd+=(--time-step-size="$otp_period"s)
+      [[ -n "$otp_digits" ]] && cmd+=(--digits="$otp_digits")
+      cmd+=("$otp_secret")
       ;;
 
     hotp)
       local counter=$((otp_counter+1))
-      cmd="$OATH -b --hotp --counter=$counter"
-      [[ -n "$otp_digits" ]] && cmd+=" --digits=$otp_digits"
-      cmd+=" $otp_secret"
+      cmd=("$OATH" --base32 --hotp --counter="$counter")
+      [[ -n "$otp_digits" ]] && cmd+=(--digits="$otp_digits")
+      cmd+=("$otp_secret")
       ;;
 
     *)
@@ -353,7 +354,7 @@ cmd_otp_code() {
       ;;
   esac
 
-  local out; out=$($cmd) || die "$path: failed to generate OTP code."
+  local out; out=$("${cmd[@]}") || die "$path: failed to generate OTP code."
 
   if [[ "$otp_type" == "hotp" ]]; then
     # Increment HOTP counter in-place
-- 
2.43.0

From cff06cc3abf97665e5997a41c0aab26808ad3ad8 Mon Sep 17 00:00:00 2001
From: Paul Wise <[email protected]>
Date: Fri, 12 May 2023 14:14:04 +0800
Subject: [PATCH 2/2] Send secrets to oathtool via stdin instead of
 command-line arguments

Check if the oathtool version supports this first.

Fixes: https://github.com/tadfisher/pass-otp/issues/167
---
 otp.bash | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/otp.bash b/otp.bash
index 7702c07..86344aa 100755
--- a/otp.bash
+++ b/otp.bash
@@ -331,6 +331,12 @@ cmd_otp_code() {
     fi
   done < <(echo "$contents")
 
+  # Check oathtool for stdin secrets feature
+  OATH_SAFE_VERSION=2.6.5
+  OATH_VERSION=$("$OATH" --version | head -n1 | tr ' ' '\n' | tail -n1)
+  printf -v OATH_VERSIONS '%s\n%s' "$OATH_SAFE_VERSION" "$OATH_VERSION"
+  [[ "$OATH_VERSIONS" = "$(sort -n <<< "$OATH_VERSIONS")" ]] && OATH_SAFE=1
+
   local cmd
   case "$otp_type" in
     totp)
@@ -339,14 +345,22 @@ cmd_otp_code() {
       [[ -n "$otp_algorithm" ]] && cmd+=(--totp="$(echo "${otp_algorithm}"|tr "[:upper:]" "[:lower:]")")
       [[ -n "$otp_period" ]] && cmd+=(--time-step-size="$otp_period"s)
       [[ -n "$otp_digits" ]] && cmd+=(--digits="$otp_digits")
-      cmd+=("$otp_secret")
+      if [[ -n "$OATH_SAFE" ]] ; then
+        cmd+=(-) # secrets on stdin
+      else
+        cmd+=("$otp_secret")
+      fi
       ;;
 
     hotp)
       local counter=$((otp_counter+1))
       cmd=("$OATH" --base32 --hotp --counter="$counter")
       [[ -n "$otp_digits" ]] && cmd+=(--digits="$otp_digits")
-      cmd+=("$otp_secret")
+      if [[ -n "$OATH_SAFE" ]] ; then
+        cmd+=(-) # secrets on stdin
+      else
+        cmd+=("$otp_secret")
+      fi
       ;;
 
     *)
@@ -354,7 +368,12 @@ cmd_otp_code() {
       ;;
   esac
 
-  local out; out=$("${cmd[@]}") || die "$path: failed to generate OTP code."
+  local out
+  if [[ -n "$OATH" && -n "$OATH_SAFE" ]] ; then
+    out=$("${cmd[@]}" <<< "$otp_secret") || die "$path: failed to generate OTP code."
+  else
+    out=$("${cmd[@]}") || die "$path: failed to generate OTP code."
+  fi
 
   if [[ "$otp_type" == "hotp" ]]; then
     # Increment HOTP counter in-place
-- 
2.43.0

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to