Skip to content

parseinvoice accepts BOLT 11 invoice with non-zero bech32 padding bits #3281

Description

@NishantBansal2003

eclair-cli parseinvoice silently accepts a BOLT 11 invoice containing non-zero bech32 padding bits, which is explicitly invalid per BIP-173. It also silently rewrites the serialized field in its response to a corrected version of the invoice, hiding the fact that the input was malformed.

Spec References

  • BOLT 11:
    "MUST parse the address as Bech32, as specified in BIP-0173"

  • BIP-173:
    "Any incomplete group at the end MUST be 4 bits or less, MUST be all zeroes, and is discarded."

In BOLT 11, I see there is a requirement for the writer: "MUST pad field data to a multiple of 5 bits, using 0s."
However, I don’t see any requirement for the reader in above case during parsing, So, I think this should also be made explicit in the spec?

Inputs

  • Invoice 1 (invalid - non-zero padding): lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqaaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqqjjc7mu
{
  "prefix": "lnbc",
  "timestamp": 524288,
  "nodeId": "02d1840657fa8d4c0fa9ce7ef698bebb4a227cc2893a0dd7b871a2fe7c5f3a85fe",
  "serialized": "lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqsaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqq7hegzf",
  "description": "",
  "paymentHash": "a1294a5280000007301a9c00000c00000000000000005004000000037fff0000",
  "features": {
    "activated": {},
    "unknown": []
  },
  "routingInfo": []
}
  • Invoice 2 (valid - zero padding): lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqsaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqq7hegzf
{
  "prefix": "lnbc",
  "timestamp": 524288,
  "nodeId": "036fc69aed4740b8d060a99047e080c699ad803381bcfa2f19be91fcc8c0b4fb1c",
  "serialized": "lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqsaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqq7hegzf",
  "description": "",
  "paymentHash": "a1294a5280000007301a9c00000c00000000000000005004000000037fff0000",
  "features": {
    "activated": {},
    "unknown": []
  },
  "routingInfo": []
}

FYI

CLN

$ lightning-cli decode lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqaaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqqjjc7mu
{
   "code": -32602,
   "message": "string: non-zero trailing bits: invalid token '\"lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqaaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqqjjc7mu\"'"
}
$ lightning-cli decode lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqsaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqq7hegzf
{
   "type": "bolt11 invoice",
   "currency": "bc",
   "created_at": 524288,
   "expiry": 3600,
   "payee": "036fc69aed4740b8d060a99047e080c699ad803381bcfa2f19be91fcc8c0b4fb1c",
   "description": "",
   "min_final_cltv_expiry": 18,
   "payment_secret": "a5294a5294a5294a5294a50210842108421ef7bdb77bdef7bfffffff881def41",
   "features": "",
   "extra": [
      {
         "tag": "q",
         "data": ""
      },
      {
         "tag": "4",
         "data": "pq9pqqq"
      },
      {
         "tag": "q",
         "data": "pqq9q8p"
      },
      {
         "tag": "a",
         "data": ""
      },
      {
         "tag": "q",
         "data": ""
      },
      {
         "tag": "a",
         "data": ""
      },
      {
         "tag": "q",
         "data": ""
      },
      {
         "tag": "q",
         "data": "jqfq5jpppp"
      },
      {
         "tag": "a",
         "data": ""
      },
      {
         "tag": "q",
         "data": ""
      },
      {
         "tag": "a",
         "data": ""
      },
      {
         "tag": "q",
         "data": ""
      },
      {
         "tag": "q",
         "data": "jqfq5jpppp"
      },
      {
         "tag": "q",
         "data": ""
      }
   ],
   "payment_hash": "a1294a5280000007301a9c00000c00000000000000005004000000037fff0000",
   "signature": "3041021c00c000000000000002819fffffffffff7087ff813fffffffffffffff022100ffffe0ffff4903e0677fffe7fffffe0000000001fffffffd294a5294a7fffffc",
   "valid": true
}

LND

$ lncli decodepayreq lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqaaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqqjjc7mu
{
    "error": "invalid incomplete group"
}
$ lncli decodepayreq lnbc1qqqsqqqqqq4q8pq9pqqqqq8pqq9q8pdqqaqqqqqaqqqqqqq2jqfq5jppppsp5555555555555555555ppppppppppaaaakaaaaaallllllzqaaaqsaqqqqqaqqqqqqq2jqfq5jpppppp55y55555qqqqqwvq6nsqqqrqqqqqqqqqqqqq9qpqqqqqqxlllqqqqqqqqqqqqqqqcqqqqqqqqqqq9qvlllllllllwzrllqfllllllllllllllllqlll5jqlqvalllelllllqqqqqqqqllllll55555555lllllqq7hegzf
{
    "destination": "036fc69aed4740b8d060a99047e080c699ad803381bcfa2f19be91fcc8c0b4fb1c",
    "payment_hash": "a1294a5280000007301a9c00000c00000000000000005004000000037fff0000",
    "num_satoshis": "0",
    "timestamp": "524288",
    "expiry": "3600",
    "description": "",
    "description_hash": "",
    "fallback_addr": "",
    "cltv_expiry": "18",
    "route_hints": [],
    "payment_addr": "a5294a5294a5294a5294a50210842108421ef7bdb77bdef7bfffffff881def41",
    "num_msat": "0",
    "features": {},
    "blinded_paths": []
}

PS: This was found during fuzzing while I was adding BOLT 11 invoice deserialization fuzz tests, and it serves as a reminder of the importance of having a good fuzz test suite for Eclair.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions