馃 Written by Claude
The related samples table on the sample page is not permission filtered, so it names samples the viewer has no access to.
snpdb/models/models_somalier.py:SomalierRelatePairs.get_for_sample is the whole query:
@staticmethod
def get_for_sample(sample: Sample):
return SomalierRelatePairs.objects.filter(Q(sample_a=sample) | Q(sample_b=sample))
No Sample.filter_for_user, and snpdb/views/views_data.py:_related_samples feeds it straight to the template, which renders for each pair:
{{ related.sample }} - Sample.__str__ is "<sample name> (<vcf name>)", so the sample name and the name of a VCF the viewer may not be able to open
- the patient name, linked to
view_patient, when the other sample has one
Following either link is correctly refused, but the names are already on the page by then. The relatedness numbers alongside them say how closely the two samples are related, which on clinical data is itself informative.
This predates the recent somalier work (#183) - that change added a Patient column and sorted the rows, but the queryset was unfiltered before it. It is the "User security for related samples" line on the #162 checklist.
Suggested fix
There is already a pattern for this on the variant page: snpdb/variant_sample_information.py:VariantZygosityCounts counts every sample but only names the ones the user can see, and exposes num_user_samples / has_hidden_samples so the template can say "showing 3 of 11" without disclosing the other 8.
The related samples table wants the same shape - filter the pairs through Sample.filter_for_user and tell the viewer how many were hidden, rather than silently dropping rows (a duplicate sample they cannot see is still something they may need to know exists).
Worth deciding at the same time whether the count itself is safe to disclose, or whether hidden pairs should be invisible entirely.
Note
settings.SOMALIER["admin_only"] limits the whole Ancestry/Relatedness tab to superusers, which would mitigate this, but it defaults to False and no deployment settings file sets it - variantgrid/settings/env/*.py only ever set SOMALIER["enabled"].
馃 Written by Claude
The related samples table on the sample page is not permission filtered, so it names samples the viewer has no access to.
snpdb/models/models_somalier.py:SomalierRelatePairs.get_for_sampleis the whole query:No
Sample.filter_for_user, andsnpdb/views/views_data.py:_related_samplesfeeds it straight to the template, which renders for each pair:{{ related.sample }}-Sample.__str__is"<sample name> (<vcf name>)", so the sample name and the name of a VCF the viewer may not be able to openview_patient, when the other sample has oneFollowing either link is correctly refused, but the names are already on the page by then. The relatedness numbers alongside them say how closely the two samples are related, which on clinical data is itself informative.
This predates the recent somalier work (#183) - that change added a Patient column and sorted the rows, but the queryset was unfiltered before it. It is the "User security for related samples" line on the #162 checklist.
Suggested fix
There is already a pattern for this on the variant page:
snpdb/variant_sample_information.py:VariantZygosityCountscounts every sample but only names the ones the user can see, and exposesnum_user_samples/has_hidden_samplesso the template can say "showing 3 of 11" without disclosing the other 8.The related samples table wants the same shape - filter the pairs through
Sample.filter_for_userand tell the viewer how many were hidden, rather than silently dropping rows (a duplicate sample they cannot see is still something they may need to know exists).Worth deciding at the same time whether the count itself is safe to disclose, or whether hidden pairs should be invisible entirely.
Note
settings.SOMALIER["admin_only"]limits the whole Ancestry/Relatedness tab to superusers, which would mitigate this, but it defaults toFalseand no deployment settings file sets it -variantgrid/settings/env/*.pyonly ever setSOMALIER["enabled"].