Skip to content

security(scoring): drop scoring-viewer read on program membership PII#351

Draft
gonzalesedwin1123 wants to merge 3 commits into
19.0from
security-scoring-viewer-membership-pii
Draft

security(scoring): drop scoring-viewer read on program membership PII#351
gonzalesedwin1123 wants to merge 3 commits into
19.0from
security-scoring-viewer-membership-pii

Conversation

@gonzalesedwin1123

Copy link
Copy Markdown
Member

Summary

The auto-installed bridge spp_scoring_programs granted
spp_scoring.group_scoring_viewer read on spp.program.membership. That
model _inherits res.partner, so the grant exposed registrant PII — identity,
addresses, email/phone, birth data, bank details, IDs, relationships, group
memberships, other programs, entitlements, enrollment state — to any
authenticated scoring viewer via direct RPC (search_read), with no program or
registry role. group_scoring_viewer implies only group_scoring_read, so this
ACL was the sole source of the access, and the only membership record rules
(disabled-partner) do not scope it to scoring-linked programs or non-PII fields.

Fix

Remove the access_spp_program_membership_scoring_viewer ACL row. Membership
access is then governed solely by spp_programs ACLs — exactly as the module's
own docs state ("spp.program.membership access controlled by spp_programs
module ACLs"):

  • A pure scoring viewer can no longer read memberships (RPC → AccessError).
  • A scoring viewer who also holds a program/registry viewer role is
    unaffected (access via spp_programs), and still sees the score columns the
    bridge adds to the membership views.
  • The spp.program read grant is kept — scoring viewers legitimately need
    to see which programs use a scoring model (action_view_programs).

No scoring-viewer flow needs membership read: the bridge's membership views are
inherited additions to spp_programs' own form/list (reached via program-viewer
menus), and the enrollment-score write path runs as a program manager, not a
scoring viewer.

Testing

  • ./spp t spp_scoring_programs11 passed, 0 failed, 0 errors (3 new, run
    as a pure group_scoring_viewer).
  • New tests: a pure scoring viewer gets AccessError reading a membership
    (fails before the fix); can still read spp.program; and a scoring+program
    viewer can still read memberships.

Notes for reviewers

  • No migration: spp_scoring_programs is not in any released tag, and ACL
    changes reload on module update regardless (removing the row drops the access).
  • No overlap with other in-flight security PRs.
  • Considered but not chosen (per the report's alternatives): a record rule
    scoping to scoring-linked programs would still expose full res.partner PII
    for those members; a non-PII summary surface is a feature, not a fix, and
    would belong in its own change. Removal matches the documented access model.
  • README generated files left to CI's pinned oca-gen.

Draft: awaiting human security review before undraft/merge.

The auto-installed spp_scoring_programs bridge granted
spp_scoring.group_scoring_viewer read on spp.program.membership. That model
_inherits res.partner, so the grant exposed registrant PII (identity, contacts,
IDs, bank details, relationships, other programs/entitlements, enrollment state)
to any scoring viewer via direct RPC, with no program or registry role and no
record rule scoping to scoring-linked programs.

Remove the membership ACL row. group_scoring_viewer's remit is scoring models
and results; membership access is governed by spp_programs ACLs (as the module
docs already state), so a scoring+program viewer is unaffected and a pure
scoring viewer no longer reaches membership PII. The spp.program read grant is
kept (scoring viewers legitimately see which programs use a scoring model).

Bump 19.0.2.0.1 -> 19.0.2.0.2 + HISTORY. No migration (module unreleased; ACL
changes reload on update). 11 tests (3 new, run as a pure scoring viewer).
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.40%. Comparing base (1caf794) to head (a6e4e50).
⚠️ Report is 3 commits behind head on 19.0.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #351      +/-   ##
==========================================
- Coverage   74.28%   67.40%   -6.88%     
==========================================
  Files         372       98     -274     
  Lines       25385     8413   -16972     
==========================================
- Hits        18857     5671   -13186     
+ Misses       6528     2742    -3786     
Flag Coverage Δ
spp_analytics ?
spp_api_v2_cycles ?
spp_api_v2_entitlements ?
spp_api_v2_gis ?
spp_api_v2_programs ?
spp_api_v2_simulation ?
spp_audit_programs ?
spp_base_common 91.07% <ø> (+0.80%) ⬆️
spp_case_demo ?
spp_case_entitlements ?
spp_case_programs ?
spp_cr_type_assign_program ?
spp_dci_compliance ?
spp_dci_demo ?
spp_dci_server_social ?
spp_demo ?
spp_demo_phl_luzon ?
spp_drims ?
spp_drims_sl ?
spp_drims_sl_demo ?
spp_farmer_registry_demo ?
spp_gis_report ?
spp_grm_demo ?
spp_indicator ?
spp_indicator_studio ?
spp_metric_service ?
spp_mis_demo_v2 ?
spp_programs 65.27% <ø> (+<0.01%) ⬆️
spp_registry 86.94% <ø> (+0.10%) ⬆️
spp_scoring_programs 35.64% <ø> (?)
spp_security 69.56% <ø> (+2.89%) ⬆️
spp_simulation ?

Flags with carried forward coverage won't be shown. Click here to find out more.
see 282 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…rmat test

Applies CI's pinned oca-gen output for the 19.0.2.0.2 changelog and ruff-format's
formatting of the new access test.
…sers

Add base.group_user so the AccessError on the membership read is provably
attributable to the missing membership ACL (and matches a realistic scoring
viewer, who is an internal user). Per staff-review nit.
@gonzalesedwin1123

Copy link
Copy Markdown
Member Author

Two independent staff reviews completed: SHIP / SOLID — membership PII vector fully closed, no regressions, clean implication chain, kept spp.program grant doesn't leak membership PII. Test hardened with base.group_user so the AccessError is provably attributable to the missing membership ACL.

Review surfaced a separate, pre-existing PII exposure outside this PR's scope: a pure scoring viewer can read all spp.scoring.result records (rule rule_scoring_result_read_all = [(1,'=',1)]), including the stored registrant_name field and inputs_snapshot/breakdown_json blobs of registrant field values. Filed as #354 (Medium) — this PR intentionally addresses only the membership grant.

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.

1 participant