Skip to content

Validate HTTPS scheme in LSPS5 URL Readable deserialization#4560

Merged
TheBlueMatt merged 1 commit into
lightningdevkit:mainfrom
vincenzopalazzo:claude/nostalgic-merkle
Apr 13, 2026
Merged

Validate HTTPS scheme in LSPS5 URL Readable deserialization#4560
TheBlueMatt merged 1 commit into
lightningdevkit:mainfrom
vincenzopalazzo:claude/nostalgic-merkle

Conversation

@vincenzopalazzo
Copy link
Copy Markdown
Contributor

Summary

  • LSPSUrl::Readable and LSPS5WebhookUrl::Readable bypassed URL validation, allowing non-HTTPS URLs (http://, ftp://, etc.) through wire protocol deserialization
  • Root cause: both Readable impls directly wrapped raw deserialized bytes without calling the validating parse()/new() constructors
  • Fix routes LSPSUrl::Readable through LSPSUrl::parse() and adds a MAX_WEBHOOK_URL_LENGTH check to LSPS5WebhookUrl::Readable

Fixes #4559

Reported-by: Thomas Kilbride of Block Security

Test plan

  • 5 regression tests added covering Readable rejection of http:// URLs, too-long URLs, and acceptance of valid HTTPS URLs
  • Full lightning-liquidity test suite passes

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented Apr 13, 2026

I've assigned @jkczyz as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

Comment thread lightning-liquidity/src/lsps5/msgs.rs
@ldk-claude-review-bot
Copy link
Copy Markdown
Collaborator

ldk-claude-review-bot commented Apr 13, 2026

Review Summary

One issue found:

  • lightning-liquidity/src/lsps5/msgs.rs:461LSPS5AppName::Readable (line 302–305) has the same bypass-the-validating-constructor bug that this PR fixes for LSPSUrl and LSPS5WebhookUrl. It skips the MAX_APP_NAME_LENGTH check. Since this PR is specifically fixing this class of bug, it should be fixed here too.

The core fix itself is correct: LSPSUrl::Readable now routes through parse(), and LSPS5WebhookUrl::Readable enforces the length limit. The url_length() change from chars().count() to .len() is a correct simplification given ASCII-only URLs.

@vincenzopalazzo vincenzopalazzo force-pushed the claude/nostalgic-merkle branch 2 times, most recently from 4c93ef8 to 5076ad9 Compare April 13, 2026 19:16
@ldk-reviews-bot ldk-reviews-bot requested a review from jkczyz April 13, 2026 19:19
@vincenzopalazzo vincenzopalazzo force-pushed the claude/nostalgic-merkle branch from 5076ad9 to 770c205 Compare April 13, 2026 19:19
The `Readable` implementations for `LSPSUrl` and `LSPS5WebhookUrl`
were bypassing URL validation, allowing non-HTTPS URLs (e.g., http://,
ftp://) to be deserialized from the wire protocol without rejection.
Only the serde `Deserialize` and `new()`/`parse()` paths were correctly
validating the HTTPS scheme.

Route `LSPSUrl::Readable` through `LSPSUrl::parse()` and add a length
check to `LSPS5WebhookUrl::Readable` so that wire-deserialized URLs
receive the same validation as JSON-deserialized ones.

Fixes lightningdevkit#4559

Reported-by: Thomas Kilbride of Block Security
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vincenzopalazzo vincenzopalazzo force-pushed the claude/nostalgic-merkle branch from 770c205 to 78df66d Compare April 13, 2026 19:22
fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
Ok(Self(Readable::read(reader)?))
let url: LSPSUrl = Readable::read(reader)?;
if url.url().len() > MAX_WEBHOOK_URL_LENGTH {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not introduced by this PR, but LSPS5AppName::Readable (line 302–305) has the exact same bypass pattern that this PR fixes for LSPSUrl and LSPS5WebhookUrl — it directly wraps the deserialized UntrustedString without calling LSPS5AppName::new(), skipping the MAX_APP_NAME_LENGTH check.

Since this PR is specifically fixing this class of bug, it would be worth fixing LSPS5AppName::Readable in the same commit to avoid leaving the identical issue in the sibling type.

Suggested change
if url.url().len() > MAX_WEBHOOK_URL_LENGTH {
let url: LSPSUrl = Readable::read(reader)?;
if url.url().len() > MAX_WEBHOOK_URL_LENGTH {
return Err(DecodeError::InvalidValue);
}

(The code here is fine — just flagging the LSPS5AppName gap since it's the same pattern.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably unrelated from the PR itself

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

❌ Patch coverage is 95.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.99%. Comparing base (4c398bb) to head (78df66d).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
lightning-liquidity/src/lsps5/url_utils.rs 33.33% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4560   +/-   ##
=======================================
  Coverage   86.99%   86.99%           
=======================================
  Files         163      163           
  Lines      108706   108744   +38     
  Branches   108706   108744   +38     
=======================================
+ Hits        94571    94605   +34     
- Misses      11655    11658    +3     
- Partials     2480     2481    +1     
Flag Coverage Δ
fuzzing 40.28% <0.00%> (+0.01%) ⬆️
tests 86.09% <95.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

@TheBlueMatt TheBlueMatt merged commit fc7be85 into lightningdevkit:main Apr 13, 2026
23 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lightning-liquidity LSPS5 URL doesn't validate https-only when deserializing

4 participants