Skip to content

security: kb.experts ranks on, and names, claims the viewer cannot retrieve #684

Description

@philluiz2323

what

experts.rank_experts filters candidate claims on status only:

for claim in store.list_claims():
    if claim.status in _EXCLUDED_STATUSES:
        continue

There is no scoping.is_visible check, so a private or cross-project claim
contributes to every number in the row and has its id handed back in
top_claim_ids.

This is the same defect #657 had in detect_themes, on the sibling read
surface. kb.recall, kb.search, kb.context, the salience sidebar and
kb.explain_ranking all scope-filter first; kb.experts does not.

repro

One public claim and three claims stamped visibility: private, agent: alice,
all on entity acme-example, read by a viewer who owns none of them:

claims this viewer may retrieve: ['pub']

rank_experts(store, "postgres", weight="count") ->
  entity: acme-example  claim_count: 4  score: 4.0
  top_claim_ids: ['pub', 'secret-0', 'secret-1']

The viewer can fetch exactly one claim and gets a count of four and two
private ids by name.

two separate problems

Disclosure. top_claim_ids is a list of claim ids the caller is invited
to go read. For an out-of-scope claim those ids are exactly what scoping
exists to withhold.

Correctness. claim_count, citation_count and score are computed
over the unfiltered set, so the ranking itself is wrong for this viewer: an
entity whose evidence is almost entirely private outranks one whose evidence
the viewer can actually read. min_claims is applied to the inflated count
too, so an entity can pass the threshold on evidence the caller will never
see. Withholding only the ids would leave the ranking lying.

expected

rank_experts filters with is_visible(claim.scope, viewer) alongside the
existing status check, resolving the viewer from config by default
(scoping.viewer_from) and accepting an explicit ViewerContext, matching
what detect_themes does after #657.

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