Repository navigation
fix(fp): distinguish an unreadable IX-F export from a genuine absence - #301
Merged
Merged
Conversation
netravnen
force-pushed
the
fix/fp-ixf-unreadable-export
branch
from
August 19, 2026 22:27
81e8958 to
87e2f97
Compare
netravnen
force-pushed
the
fix/fp-ixf-unreadable-export
branch
from
August 19, 2026 22:28
87e2f97 to
7b8e529
Compare
netravnen
force-pushed
the
fix/fp-ixf-unreadable-export
branch
from
August 19, 2026 22:29
7b8e529 to
0ce4430
Compare
netravnen
force-pushed
the
fix/fp-ixf-unreadable-export
branch
from
August 19, 2026 22:31
0ce4430 to
5f46b0a
Compare
netravnen
force-pushed
the
fix/fp-ixf-unreadable-export
branch
from
August 19, 2026 23:05
5f46b0a to
41033df
Compare
The per-row "Verify IX-F" check treated an export it could not read as proof that the network is not in the feed. extractIxfMatchForAsnIp coerced a missing or non-array member_list to [], found nothing in it, and returned "none" -- which the panel renders as "IX-F export has no entry for AS<n> at this exchange at all" directly above a "Remove netixlan entry" button. A 200-OK CDN error page, a renamed schema, a feed that moved, or an ixlan whose ixf_ixp_member_list_url points at a different exchange all take that path, so an admin acting on a confident negative could delete a netixlan row the feed never actually contradicted. "none" is a positive claim, not a default. It is now returned only from an export that could be read, and everything else reports as inconclusive with no destructive control offered. Changes: - extractIxfMatchForAsnIp returns matched: "unreadable" with a machine `reason` when member_list is missing, non-array or empty, and when there is no target ASN to look up. All returns carry `reason` so the shape stays uniform. - Add renderUnreadableIxfExportResult: names the check inconclusive, explains that this is not evidence for removal, and shows the source URL so the admin can inspect the feed. It deliberately offers no remove or resolve button, and says so in its docblock. - Branch to it before the "none" case in the verify flow; document on renderNoIxfEntryResult why it is now unreachable on a false negative. Security: - Closes a path where unvalidated third-party data (an exchange's own export URL, fetched cross-origin) could induce an admin to delete a live netixlan record. The feed is not attacker-controlled in the usual sense, but it is third-party, unauthenticated, and frequently broken. Testing: - node --test: 507 tests, 506 pass, 1 skipped (live tests are opt-in). - Replaced the test that asserted the old conflated behavior. New cases cover null body, empty object, non-IX-F JSON, non-array member_list, and present-but-empty member_list -- each must be "unreadable" and explicitly not "none". - Kept a case proving "none" still fires for a readable export that genuinely lacks the ASN, so the Remove path is not silently dead. - Removed the guard and confirmed 4 failures, then restored. Backwards Compatibility: - extractIxfMatchForAsnIp gains a fourth `matched` value and a `reason` field. Its only caller is updated in the same commit; it is exported on the test hooks but has no other consumer. buildIxfDiff already keys off matched === "ip" and returns [] for the new state unchanged. Assisted-by: Claude:claude-opus-5
netravnen
force-pushed
the
fix/fp-ixf-unreadable-export
branch
from
August 19, 2026 23:06
41033df to
7e736c8
Compare
netravnen
marked this pull request as ready for review
August 19, 2026 23:07
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The per-row "Verify IX-F" check treated an export it could not read as
proof that the network is not in the feed. extractIxfMatchForAsnIp
coerced a missing or non-array member_list to [], found nothing in it,
and returned "none" -- which the panel renders as "IX-F export has no
entry for AS at this exchange at all" directly above a "Remove
netixlan entry" button. A 200-OK CDN error page, a renamed schema, a feed
that moved, or an ixlan whose ixf_ixp_member_list_url points at a
different exchange all take that path, so an admin acting on a confident
negative could delete a netixlan row the feed never actually contradicted.
"none" is a positive claim, not a default. It is now returned only from
an export that could be read, and everything else reports as
inconclusive with no destructive control offered.
Changes:
reasonwhen member_list is missing, non-array or empty, and whenthere is no target ASN to look up. All returns carry
reasonso theshape stays uniform.
explains that this is not evidence for removal, and shows the source
URL so the admin can inspect the feed. It deliberately offers no
remove or resolve button, and says so in its docblock.
renderNoIxfEntryResult why it is now unreachable on a false negative.
Security:
export URL, fetched cross-origin) could induce an admin to delete a
live netixlan record. The feed is not attacker-controlled in the usual
sense, but it is third-party, unauthenticated, and frequently broken.
Testing:
cover null body, empty object, non-IX-F JSON, non-array member_list,
and present-but-empty member_list -- each must be "unreadable" and
explicitly not "none".
genuinely lacks the ASN, so the Remove path is not silently dead.
Backwards Compatibility:
matchedvalue and areasonfield. Its only caller is updated in the same commit; it is exported on
the test hooks but has no other consumer. buildIxfDiff already keys off
matched === "ip" and returns [] for the new state unchanged.
Assisted-by: Claude:claude-opus-5
Stack created with GitHub Stacks CLI • Give Feedback 💬