Skip to content

T91: organization-wide disclosure policy - #2

Open
tomj12k wants to merge 2 commits into
mainfrom
security/t91
Open

tomj12k wants to merge 2 commits into
mainfrom
security/t91

Conversation

@tomj12k

@tomj12k tomj12k commented Sep 10, 2026

Copy link
Copy Markdown

Tracked internally as T91. This public description intentionally omits the finding details.

Scope: adds an organization-default disclosure policy for repositories that do not provide their own.

The policy deliberately avoids a static repository inventory so it cannot go stale or disclose non-public repository names.

Tracked as T91. Details in the private security repository.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5xdKhPXJT4HMWwUyENiu1
@tomj12k

tomj12k commented Sep 13, 2026

Copy link
Copy Markdown
Author

Exact-head review at 5c39502 found no blocking issue. GitHub's current documentation confirms that a public organization .github repository supplies SECURITY.md to repositories of any visibility when they do not define their own policy, and repository-local files take precedence as this text says.

Trade-off: one organization-wide response promise is easier to discover and maintain, while repository-specific support windows remain opt-in through local overrides.

Uncertainty: source review cannot prove that security@morelitea.com is monitored or that the 48-hour acknowledgement target is staffed. Those are operating controls and should be exercised with a test report after merge.

@tomj12k

tomj12k commented Sep 13, 2026

Copy link
Copy Markdown
Author

Reviewed at 5c3950290975. No change pushed — the one finding cannot be fixed by a commit.

Checked, and correct

The precedence claim holds. "GitHub applies this policy to every Morelitea repository that has no policy of its own" is accurate including for private repositories, which is the part I expected to be wrong. Per GitHub's own documentation: "GitHub will use and display default files for any repository owned by the account, regardless of the destination repository's visibility, that does not have its own file of that type" — with the constraint that "the .github repository must be public", which it is. Verified against the primary source rather than from memory, because a policy that silently fails to apply to half the estate is worse than no policy.

The precedence is real and currently exercised once. Of the twelve repositories I surveyed, exactly one — initiative — carries its own SECURITY.md, and it gives a reporting route rather than merely describing architecture, so nothing falls through the gap this document creates.

The reporting address routes. morelitea.com resolves to 10 mail.protonmail.ch / 20 mailsec.protonmail.ch. A policy pointing at an unroutable mailbox drops reports in silence, so it is worth confirming rather than assuming.

The archived-repository paragraph is consistent with reality. PathKit is archived and has an open pull request that cannot be merged for exactly that reason, which is the case the paragraph describes.

Finding: the private channel this document assumes is off almost everywhere

The policy says "Please do not open a public issue." That instruction needs somewhere else to go. GitHub's own private reporting channel is the obvious one, and it is enabled on one repository out of five:

Mycorzha-Map                 archived=false  private-reporting=false
initiative                   archived=false  private-reporting=true
initiative-github            archived=false  private-reporting=false
initiative-app-kit           archived=false  private-reporting=false
.github                      archived=false  private-reporting=false
PathKit                      archived=true   (n/a — archived)

The one repository where the "Report" button works is the one repository that does not inherit this policy. On the four that do, a researcher who follows the instruction is left with email alone; a researcher who does not find the email is left with a public issue, which is the outcome the sentence exists to prevent.

Email does work, so this is a narrowed channel rather than a closed one — hence a finding on the rollout, not a blocker on the document. But the document is what makes the setting matter, and this pull request is the moment the document arrives.

Remediation is a repository setting, not a commit, which is why nothing is pushed. Settings → Code security → Private reporting, on each of the four, or at the organization level with "enable for new repositories" so this does not need doing again.

Things I am not certain about

  1. "Acknowledgement within 48 hours." A real commitment with no visible owner. I have no way to check whether anyone is on the hook for the security@ mailbox, and the policy is more credible without the number than with an unmet one. Worth confirming who holds it before this merges — it is the one line a reporter will quote back.
  2. Scope says our deployment configuration and CI workflows are in scope; What we ask says to test against your own deployment. For a finding in deployment configuration there is no "your own deployment" to test against, so those two paragraphs point a reporter in opposite directions. Not a defect in either sentence — worth one clause saying configuration findings are read rather than exercised.
  3. security@morelitea.com appears here and in initiative/SECURITY.md. Two documents, one address, and only one of them will be updated if it ever changes. Not worth solving today; worth knowing.

Reviewer: Claude Opus 5 (1M context). GitHub behaviour verified against docs.github.com; repository states read from the API at review time.

This pull request had zero checks. Nothing in the repository ran on a change,
so the file it adds could have merged broken and nobody would have seen it --
and this file is the one GitHub shows on every repository in the organization
that has no policy of its own, so broken here is broken everywhere at once.

The check asserts the things that make it a policy rather than a page: a
reporting route, a section telling a reporter what happens next, a scope, and
relative links that resolve. Nothing about wording.

Demonstrated failing rather than assumed: removing the address, the "What to
expect" heading or the "Scope" heading each exits 1 naming the cause, and so
does a link to a file that is not here. The unmodified file passes.

Actions pinned to commits rather than tags, for the reason T59 gives, reusing
the SHAs the initiative workflows already carry. No package.json: the check is
one script against one file, and a dependency would be a supply chain for
something that reads Markdown.

Tracked as T91.
@tomj12k

tomj12k commented Sep 14, 2026

Copy link
Copy Markdown
Author

This PR had zero checks. It has one now, and it passes: Disclosure policy=SUCCESS at bb81667.

Worth fixing here rather than later, because this is the file GitHub serves on every repository in the organization that has no policy of its own. Broken here is broken everywhere at once, and nothing consumes it — no build reads a disclosure policy, so a bad link or a lost section shows up nowhere.

What the check asserts — the things that make it a policy rather than a page:

  • a reporting route exists (an address, or a private advisory link)
  • a section tells a reporter what happens next
  • a scope is stated
  • every relative link resolves to a file in this repository

Nothing about wording. It is a structural check, not a style one.

Demonstrated failing, not assumed:

remove reporting route  -> rc=1    - no reporting route: neither an email address nor a private advisory link
remove expectations     -> rc=1    - no "What to expect" section — a reporter is told nothing about what follows
remove scope            -> rc=1    - no "Scope" section
add broken link         -> rc=1    - link "broken" points at docs/missing.md, which is not in this repository
unmodified              -> rc=0    SECURITY.md: reporting route, expectations, scope and links all present

Two deliberate choices: Actions are pinned to commit SHAs rather than tags — the reason T59 gives — reusing the SHAs the initiative workflows already carry. And there is no package.json: the check is one script against one file, and a dependency would be a supply chain for something that reads Markdown.

The earlier finding on this PR stands unchanged — private vulnerability reporting is still enabled on one public repository out of five, and that one does not inherit this policy. That is a settings change, not a commit.


Reviewer: Claude Opus 5 (1M context).

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