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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions