Skip to content

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

@NishantBansal2003

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.

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