askrene-getroutes: add test for source==destination
What changed, and why it matters
This commit adds a test that checks Core Lightning's routing plugin (askrene) properly rejects a request where the payment source and destination are the same node. The test is marked as expected to fail for now, meaning the bug it checks for likely still exists in the code. If triggered, such a request could crash the lightning daemon instead of returning a clean error.
Treat this as a low-severity bug report rather than an active vulnerability. The maintainer should implement input validation in `getroutes` to reject `source == destination` with the documented RPC error, then remove the `xfail` marker. Users should avoid passing identical source and destination nodes to `getroutes` until the fix lands.
Security signals we found
Potential denial-of-service via malformed RPC input (source==destination)
Test marked xfail indicates unpatched behavior
Crash of lightningd suggested by test docstring
Evidence from the diff
The patch adds an xfail pytest case test_bad_user_entries in tests/test_askrene.py. It creates an askrene layer and channel, then calls getroutes with source == destination. The test expects an RpcError with message matching ‘source and destination must be different’. Because it is decorated with @pytest.mark.xfail(strict=True), the current implementation does not yet satisfy the expected behavior, suggesting getroutes either crashes or returns an incorrect response when source equals destination.
Changed components
tests/test_askrene.pyaskrene getroutes RPC handlerInspect captured patch +42 / −0
diff --git a/tests/test_askrene.py b/tests/test_askrene.py
index 9fbc9e70..6d05583f 100644
--- a/tests/test_askrene.py
+++ b/tests/test_askrene.py
@@ -2667,3 +2667,45 @@ def test_impossible_payment(node_factory):
final_cltv=5,
maxparts=1,
)
+
+
+@pytest.mark.xfail(strict=True)
+def test_bad_user_entries(node_factory):
+ """Test bad user entries that should result in an RPC error and not crash
+ lightningd."""
+ l1 = node_factory.get_node()
+ node1 = "020000000000000000000000000000000000000000000000000000000000000001"
+ node2 = "020000000000000000000000000000000000000000000000000000000000000002"
+ million_sats = 1000000000
+ l1.rpc.askrene_create_layer("mylayer")
+ l1.rpc.askrene_create_channel(
+ layer="mylayer",
+ source=node1,
+ destination=node2,
+ short_channel_id="0x0x1",
+ capacity_msat=million_sats,
+ )
+ l1.rpc.askrene_update_channel(
+ layer="mylayer",
+ short_channel_id_dir="0x0x1/0",
+ enabled=True,
+ htlc_minimum_msat=0,
+ htlc_maximum_msat=million_sats,
+ fee_base_msat=0,
+ fee_proportional_millionths=0,
+ cltv_expiry_delta=18,
+ )
+
+ # Try querying getroutes with source==destination
+ with pytest.raises(
+ RpcError,
+ match=r"source and destination must be different",
+ ):
+ l1.rpc.getroutes(
+ source=node1,
+ destination=node1,
+ amount_msat=1000,
+ layers=["mylayer"],
+ maxfee_msat=2000,
+ final_cltv=5,
+ )
Why this scored 34/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.