diff --git a/_static/psrt-coordinator-report.html b/_static/psrt-coordinator-report.html new file mode 100644 index 000000000..280dd24e7 --- /dev/null +++ b/_static/psrt-coordinator-report.html @@ -0,0 +1,3 @@ +

+

Received a report...

...via security@python.org?

PSRT admin reviews email

Reject

Accept

PSRT asks reporter to open via GHSA

...via GHSA

GHSA in state “Triage”

+

diff --git a/_static/psrt-coordinator-report.mermaid b/_static/psrt-coordinator-report.mermaid new file mode 100644 index 000000000..9ad3bae96 --- /dev/null +++ b/_static/psrt-coordinator-report.mermaid @@ -0,0 +1,18 @@ +flowchart TD + report[Received a report...] + via_security_at_python_dot_org[...via security@python.org?] + psrt_admin_review[PSRT admin reviews email] + email_reject[Reject] + email_accept[Accept] + open_via_ghsa[PSRT asks reporter to open via GHSA] + via_ghsa[...via GHSA] + ghsa_triage[GHSA in state “Triage”] + + report-->via_security_at_python_dot_org + via_security_at_python_dot_org-->psrt_admin_review + psrt_admin_review-->email_reject + psrt_admin_review-->email_accept + email_accept-->open_via_ghsa + open_via_ghsa-->ghsa_triage + report-->via_ghsa + via_ghsa----->ghsa_triage diff --git a/_static/psrt-coordinator-triage.html b/_static/psrt-coordinator-triage.html new file mode 100644 index 000000000..f10f93835 --- /dev/null +++ b/_static/psrt-coordinator-triage.html @@ -0,0 +1,3 @@ +

+

GHSA in state “Triage”

PSRT member volunteers as Coordinator

After 3 days idle, Coordinator is auto-assigned

GHSA ticket updated to set Credit for Coordinator

Cooridnator determines whether report...

...is a non-issue or invalid

...is a bug but not security relevant

...is a security issue

Coordinator opens a public GitHub issue

Close the GHSA ticket

Move GHSA ticket to “Draft”

+

diff --git a/_static/psrt-coordinator-triage.mermaid b/_static/psrt-coordinator-triage.mermaid new file mode 100644 index 000000000..c43a88c65 --- /dev/null +++ b/_static/psrt-coordinator-triage.mermaid @@ -0,0 +1,25 @@ +flowchart TD + ghsa_triage[GHSA in state “Triage”] + psrt_member_volunteers[PSRT member volunteers as Coordinator] + psrt_member_assigned[After 3 days idle, Coordinator is auto-assigned] + coordinator_assigned[GHSA ticket updated to set Credit for Coordinator] + coordinator_determines[Cooridnator determines whether report...] + report_is_a_non_issue[...is a non-issue or invalid] + report_is_a_bug_but_not_security[...is a bug but not security relevant] + report_is_a_security_issue[...is a security issue] + coordinator_opens_public_github_issue[Coordinator opens a public GitHub issue] + close_ghsa[Close the GHSA ticket] + ghsa_draft[Move GHSA ticket to “Draft”] + + ghsa_triage-->psrt_member_volunteers + ghsa_triage-->psrt_member_assigned + psrt_member_volunteers-->coordinator_assigned + psrt_member_assigned-->coordinator_assigned + coordinator_assigned-->coordinator_determines + coordinator_determines-->report_is_a_non_issue + coordinator_determines-->report_is_a_bug_but_not_security + coordinator_determines-->report_is_a_security_issue + report_is_a_non_issue--->close_ghsa + report_is_a_bug_but_not_security-->coordinator_opens_public_github_issue + coordinator_opens_public_github_issue-->close_ghsa + report_is_a_security_issue--->ghsa_draft diff --git a/developer-workflow/psrt.rst b/developer-workflow/psrt.rst index 543e09358..dbf51f810 100644 --- a/developer-workflow/psrt.rst +++ b/developer-workflow/psrt.rst @@ -56,7 +56,7 @@ Below are the responsibilities of PSRT members: necessary to make a determination whether a report is a vulnerability and developing a patch. Coordinators are encouraged to involve members of the core team to make the best decision for each report rather than working in isolation. -* As a Coordinator, calculating the severity using CVSS and authoring advisories +* As a Coordinator, calculating the severity using CVSSv4 and authoring advisories to be shared on `security-announce@python.org`_. These advisories are used for CVE records by the `PSF CVE Numbering Authority`_. * Coordinators that can no longer move a report forwards for any reason must @@ -80,94 +80,190 @@ following additional responsibilities: * Running nomination elections, including counting final votes and giving the Steering Council an opportunity to veto nominations via email. -Vulnerability report triage ---------------------------- +Triaging a vulnerability report +------------------------------- + +PSRT members coordinate reports from when they are first submitted +to a "finished" state. Finished states include +marking a report as a "non-issue", opening a public issue on GitHub, +or a merged patch with an accompanying CVE and advisory to +``security-announce@python.org``. Reports should reach a finished +state within 90 days of being received by the PSRT. -Vulnerability reports are sent to one of two locations, -the long-standing ``security@python.org`` mailing list -or using the private vulnerability reporting feature -of GitHub Security Advisories (GHSA). +Reports enter the system through ``security@python.org`` or +on a project GitHub Security Advisory (GHSA) ticketing system. +For projects that use GHSA, reports to ``security@python.org`` +should have reporters `re-open their report using GHSA`_. + +.. raw:: html + :file: ../_static/psrt-coordinator-report.html -For reports sent to ``security@python.org``, a PSRT admin -will triage the report and if the report seems plausible -(that is, not spam and for the correct project) will reply with -instructions on how to report the vulnerability on GitHub. +.. _re-open their report using GHSA: #submit-using-github-security-advisories + +New report in GitHub Security Advisories (GHSA) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a report is in GHSA, a "Coordinator" must be assigned +to be responsible for moving the report through the process. +The "Coordinator" role is assigned using a "Credit" in a GHSA ticket +(Select 'Edit' > 'Credit' > Add GitHub username and the role 'Coordinator'). + +.. warning:: + Assigning the "Coordinator" role to each GHSA ticket is important, + as this metadata records whether a PSRT member is + `"active" according to PEP 811`_ to avoid being removed due to inactivity. + +.. _"active" according to PEP 811: https://peps.python.org/pep-0811/#psrt-membership-policy + +If a GHSA ticket is idle for three days without a coordinator +assigned a PSRT member who is not a Release Manager +or Steering Council member will be automatically assigned +as coordinator by the PSRT bot. +If a coordinator can't complete the process +they must find a replacement coordinator in the PSRT +and re-assign the GHSA ticket. -If the reporter doesn't want to use GitHub's Security Advisories feature -then the PSRT admins can create a draft report on behalf of the reporter. +.. raw:: html + :file: ../_static/psrt-coordinator-triage.html -Coordinating a vulnerability report ------------------------------------ +Determining whether a report is a vulnerability +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Each report will have a member of the PSRT assigned as the "coordinator". -The coordinator will be responsible for following the below process and -will be publicly credited on vulnerability records post-publication. +The coordinator will make a determination about a report, either +marking the ticket as a non-issue, as an issue that isn't a security +vulnerability, or as a security vulnerability. If the Coordinator needs +help from core team experts in making the determination, the +experts may be added as 'Collaborators' to the GHSA ticket. +Accepted security vulnerabilities will be moved to the 'Draft' state in GHSA. -If a coordinator can't complete the process for any reason (time obligation, -vacation, etc.) they must find a replacement coordinator in the PSRT -and reassign the vulnerability report appropriately. +If the report isn't a vulnerability, coordinators close the GHSA ticket +after optionally opening a public GitHub issue. Note that reporters often +will not open a GitHub issue on their own, as there is no longer an incentive +for them to do so without a CVE being assigned. + +Remediating a vulnerability report +---------------------------------- + +Once a report has been accepted as a vulnerability, the remediation +development process begins. Coordinators move the GHSA ticket to a 'Draft' +state using the green 'Accept as Draft' button. Once in this state, +the PSRT bot will automatically assign a CVE ID from the Python Software +Foundation CVE Numbering Authority. + +Once a vulnerability has been accepted there are three things +the Coordinator must prepare before sending an advisory and +closing the GHSA ticket: + +* Severity calculated using CVSSv4. +* Pull request containing the fix merged with a public GitHub issue. +* Advisory title and short description of the vulnerability. + +Severity scoring +~~~~~~~~~~~~~~~~ + +Severity of a vulnerability can be difficult to assess +objectively due to not knowing how software is used +in all situations. Severity is calculated from expected +or known use, not from worst-case hypothetical scenarios. + +The PSRT and PSF CNA use `CVSSv4`_ for calculating +the severity of a vulnerability. GHSA tickets provide a +CVSSv4 calculator within the ticket UI. Note that GitHub defaults to CVSSv3, +change the scoring algorithm to CVSSv4 before scoring in the ticket UI. +As with all aspects of PSRT operations, coordinators are encouraged to ask +for help in calculating a severity from other PSRT members. + +.. _CVSSv4: https://www.first.org/cvss/v4.0/ + +Developing a patch privately +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Patch development can initially be done privately by selecting the +'Start a temporary private fork' button within the GHSA ticket. Note that +due to the size of Git repositories, this fork repository may +take several minutes to create. Once the fork has been created any PSRT member +or GHSA collaborator can clone the fork and develop a fix and push a branch: + +.. code-block:: shell + + git clone https://github.com/python/cpython-ghsa-abcd-efgh-ijkl.git + cd cpython-ghsa-abcd-efgh-ijkl + git checkout -b advisory-fix-1 + + # (develop a fix) + + git add ... + git commit -m "Fix" + git push origin advisory-fix-1 + +From here a pull request can be opened within the GHSA ticket +to be reviewed privately. The coordinator can add core team experts +as collaborators as necessary to the GHSA to develop the patch and to review +the patch if the expertise for patch development or review +aren't available within PSRT. Coordinators are not necessarily responsible +with developing patches themselves: only with seeing that a patch is +developed in a timely fashion by involving experts as necessary. + +Once the patch has been approved +a public GitHub issue and pull request can be opened. +Generate a blurb in the category ``Security`` for the public pull request. +Public issues and pull requests for security fixes should use the +:gh-label:`type-security` label. + +To quickly pull a patch file from a GHSA pull request, you +can append ``.patch`` to the pull request URL, like so: + +.. code-block:: shell + + curl https://github.com/python/cpython-ghsa-abcd-efgh-ijkl/pull/1.patch \ + --output ghsa-abcd-efgh-ijkl.patch + +This patch can then be applied and pushed to the public GitHub repository: + +.. code-block:: shell + + git remote -v + origin ssh://git@github.com/.../cpython (fetch) + origin ssh://git@github.com/.../cpython (fetch) + + git checkout -b branch-name + git apply ./ghsa-abcd-efgh-ijkl.patch + git push origin branch-name + +.. warning:: **IMPORTANT:** CPython's backport infrastructure + is used for tracking backported patches. Use **one GitHub issue + per CVE** to accurately track backports of vulnerability fixes. + For new CVEs, even when related to a previous issue, **open a + new GitHub issue** to accurately track fixed versions. -Coordinators are expected to collaborate with other PSRT and core team members -when needed for guidance on whether the report is an actual vulnerability, -severity, advisory text, and fixes. +.. warning:: **IMPORTANT:** Don't select the green 'Merge pull request' + or 'Publish advisory' buttons within GHSA. Advisories are published + to the mailing list, and the 'Merge pull request' button within + GHSA bypasses all continuous integration and branch protection + steps. Use a public pull request instead. + +Publishing an advisory +~~~~~~~~~~~~~~~~~~~~~~ + +Once the vulnerability fix has been merged into the main branch via a +public GitHub pull request, an advisory must be published. +The advisory requires the severity, +a title, and a short description of the vulnerable module, functions, +behavior and fix. This short description can optionally include mitigation steps +if applying the patch isn't the only way to mitigate the vulnerability. -**The vulnerability coordination process is:** +* Send an email to the ``security-announce@python.org`` mailing list + using the `advisory template`_, including title, severity, description. +* The advisory email will be received by PSF CVE Numbering Authority + operators and used to publish a CVE record. +* Begin the backporting process for all Python branches still receiving + security updates. Add the :gh-label:`type-security` and :gh-label:`release-blocker` labels + to each backport pull request so that release managers can find them prior + to releasing. -* Coordinator will determine whether the report constitutes a vulnerability. If the report isn't a vulnerability, - the reporter should be notified appropriately. Close the GHSA report, the report can be reopened if - sufficient evidence is later obtained that the report is a vulnerability. +After an advisory email is sent, the GHSA ticket can be closed. -* After a vulnerability report is accepted, a Common Vulnerabilities and Exposures (CVE) ID must be assigned. If this is not done - automatically, then a CVE ID can be obtained by the coordinator sending an email to ``cna@python.org``. - No details about the vulnerability report need to be shared with the PSF CVE Numbering Authority (CNA) for a CVE ID to be reserved. - -* If the report is a vulnerability, the coordinator will determine the severity of the vulnerability. Severity is one of: - **Low**, **Medium**, **High**, and **Critical**. Coordinators can use their knowledge of the code, how the code is likely used, - or another mechanism like Common Vulnerability Scoring System (CVSS) for determining a severity. Add this information to the GitHub Security Advisory. - -* Once a CVE ID is assigned, the coordinator will share the acceptance and CVE ID with the reporter. - Use this CVE ID for referencing the vulnerability. The coordinator will ask the reporter - if the reporter would like to be credited publicly for the report and if so, how they would like to be credited. - Add this information to the GitHub Security Advisory. - -* The coordinator authors the vulnerability advisory text. The advisory must include the following information: - - * Title should be a brief description of the vulnerability and affected component - (for example, "Buffer over-read in SSLContext.set_npn_protocols()") - - * Short description of the vulnerability, impact, and the conditions where the affected component is vulnerable, if applicable. - - * Affected versions. This could be "all versions", but if the vulnerability exists in a new feature - or removed feature then this could be different. Include versions that are end-of-life in this calculation - (for example, "Python 3.9 and earlier", "Python 3.10 and later", "all versions of Python"). - - * Affected components and APIs. The module, function, class, or method must be specified so users can - search their codebase for usage. For issues affecting the entire project, this can be omitted. - - * Mitigations for the vulnerability beyond upgrading to a fixed version, if applicable. - - This can all be done within the GitHub Security Advisory UI for easier collaboration between reporter and coordinator. - -* The coordinator determines the fix approach and who will provide a fix. - Some reporters are willing to provide or collaborate to create a fix, - otherwise relevant core team members can be invited to collaborate by - the coordinator. - - * For **Low** and **Medium** severity vulnerabilities it is acceptable - to develop a fix in public. - The pull request must be marked with the ``security`` and ``release-blocker`` - labels so that a release is not created without including the fix. - - * For **High** and **Critical** severity vulnerabilities the fix must be - developed privately using GitHub Security Advisories' "Private Forks" feature. - Core team members can be added to the GitHub Security Advisory via "collaborators" - to work on the fix together. Once a fix is approved privately and tested, - a public issue and pull request can be created with - the ``security`` and ``release-blocker`` labels. - -* Once the pull request is merged the advisory can be published. The coordinator will send the advisory by email - to ``security-announce@python.org`` using the below template. Backport labels must be added as appropriate. - After the advisory is published a CVE record can be created. +.. _advisory template: #advisory-email Handling code signing certificate reports ----------------------------------------- @@ -210,7 +306,8 @@ These template responses should be used as guidance for messaging in various points in the process above. They are not required to be sent as-is, please feel free to adapt them as needed for the current context. -**Directing to GitHub Security Advisories:** +Submit using GitHub Security Advisories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. highlight:: none @@ -218,16 +315,12 @@ please feel free to adapt them as needed for the current context. Thanks for submitting this report. We use GitHub Security Advisories for triaging vulnerability reports, - are you able to submit your report directly to GitHub? + please submit your report here: https://github.com/python/cpython/security/advisories/new - If you're unable to submit a report to GitHub (due to not having a GitHub - account or something else) let me know and I will create a GitHub Security - Advisory on your behalf, although you won't be able to participate directly - in discussions. - -**Rejecting a vulnerability report:** +Rejecting a vulnerability report +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: @@ -236,35 +329,18 @@ please feel free to adapt them as needed for the current context. If you are interested in working on this further, you can optionally open a public issue on GitHub. -**Accepting a vulnerability report:** - -:: - - Thanks for your report. We've determined that the report - is a vulnerability. We've assigned {CVE-YYYY-XXXX} and determined - a severity of {Low,Medium,High,Critical}. Let us know if you disagree - with the determined severity. - - If you would like to be publicly credited for this vulnerability as the - reporter, please indicate that, along with how you would like to be - credited (name or organization). - - Please keep this vulnerability report private until we've published - an advisory to ``security-announce@python.org``. - -**Advisory email:** +Advisory email +~~~~~~~~~~~~~~ :: Title: [{CVE-YYYY-XXXX}] {title} - There is a {LOW, MEDIUM, HIGH, CRITICAL} severity vulnerability - affecting {project}. + There is a {LOW, MEDIUM, HIGH, CRITICAL} severity vulnerability affecting {project}. {description} - Please see the linked CVE ID for the latest information on - affected versions: + Please see the linked CVE ID for the latest information on affected versions: * https://www.cve.org/CVERecord?id={CVE-YYYY-XXXX} * {pull request URL}