Add security policy and supporting documentation - #19722
andrewleech wants to merge 3 commits into
Conversation
a994c62 to
587470f
Compare
| ``ptr``, ``ptr8``, ``ptr16`` and ``ptr32`` types with no bounds checking. | ||
| * ``@micropython.asm_thumb`` and ``@micropython.asm_rv32``: inline assembly. | ||
| * Native C extension modules (``dynruntime.h`` / ``.mpy`` native modules). | ||
|
|
There was a problem hiding this comment.
Should the list not also include direct flash modification? Some ports provide an API.
There was a problem hiding this comment.
Good catch, added.
| Scope | ||
| ----- | ||
|
|
||
| This policy covers the MicroPython core (``py/``, ``extmod/``, ``shared/``), the maintained ports |
There was a problem hiding this comment.
I recommend that all micropython-lib modules are also explicitly included, whether they are actually frozen in a standard firmware, or mip-installed.
There was a problem hiding this comment.
Yep, agreed, I've added it. Python code has its own share of security bugs even if it can't corrupt memory.
It'd probably want a small SECURITY.md in micropython-lib pointing back here too, I can do that separately if this lands.
| untrusted input reaches a managed API and causes memory corruption, and in any path that lets | ||
| untrusted data escape the managed model without the firmware author having opted out of it. | ||
|
|
||
| Issues arising solely from the features listed in :ref:`security_unmanaged`, or from loading |
There was a problem hiding this comment.
rst formatting not correct
There was a problem hiding this comment.
I think that's just GitHub's preview, it doesn't know Sphinx roles. It renders as a normal link in the built docs, same as the other :ref:`...` uses in docs/develop/. Or did you mean something else here?
There was a problem hiding this comment.
It renders as a normal link in the built docs,
I was indeed trusting the GH .rst preview
| Leaving the managed subset | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| The following documented mechanisms deliberately leave the managed subset and carry the same |
There was a problem hiding this comment.
I needed to read this a few times before I could understand it (I think).
"The managed subset" is a concept referred to , but is not explained nor discussed outside this paragraph
As this defines an important boundary , I suggest to document it in clear language that avoids unneeded inference, and limits possible misunderstanding by non-native speakers.
There was a problem hiding this comment.
Yeah fair, that term was doing more harm than good. I've reworded the section without it, see if that reads better.
| bytecode, so a malformed ``.mpy`` can crash or corrupt the runtime. The ``.mpy`` format is a trusted | ||
| deployment artefact, not an untrusted-input format; as with firmware images, a product that stores | ||
| or receives ``.mpy`` files must protect their integrity before loading them. Loading ``.mpy`` files | ||
| from an untrusted source is equivalent to running untrusted native code. |
There was a problem hiding this comment.
should this also mention loading .mpy modules from ROMFS that are deployed through mpremote+mpy-cross , are they less trusted than frozen .mpy modules ?
There was a problem hiding this comment.
Good point, I've added a bit on this. Frozen is really only safer when nobody else can get at the REPL or filesystem, so I've toned down the "ship frozen bytecode" advice as well.
|
Thanks for putting this together, |
587470f to
f1d45ae
Compare
|
Possibly worth some note about how to report security issues with the surrounding ecosystem and tooling of MicroPython, since it launches straight into Me - reading "Guidance for product developers" - aah yes, I do none of that 😭 Almost by necessity, mind. |
| * The affected port, board, and any non-default build configuration (``mpconfigport.h`` / | ||
| ``mpconfigboard.h`` options, native modules, ``MICROPY_PREVIEW_VERSION_2``). | ||
| * The reproducing code pasted directly into the report, not linked to an external repository (which | ||
| may change), and minimised to the smallest snippet that still triggers the fault. |
There was a problem hiding this comment.
Might be easier just to say A minimum reproducible example pasted directly into the report.
| <https://github.com/micropython/micropython-lib>`__, whether they are frozen into an official build | ||
| or installed with ``mip``. Code you have modified from an official release is out of scope. | ||
|
|
||
| A memory-safety defect in MicroPython's own C code that can be triggered from ordinary Python code, |
There was a problem hiding this comment.
Redundant possessive "own". (bugbear of mine 😭)
Could probably just be A memory-safety defect in MicroPython that can since MicroPython also contains frozen Python bytecode, and may rely on it more in future.
There was a problem hiding this comment.
Thanks, done. Good point about frozen code too.
| reports where untrusted input, such as network data or a file, causes memory corruption. | ||
|
|
||
| Vulnerabilities in MicroPython's Python code, such as frozen modules and micropython-lib packages, | ||
| are also in scope. Ordinary Python code can't corrupt memory, but it can still mishandle untrusted |
There was a problem hiding this comment.
I think this still holds given the amendment above, this contradiction becomes a clarification.
There was a problem hiding this comment.
Agreed, reads better now.
| protocol incorrectly. | ||
|
|
||
| Issues arising solely from the features listed in :ref:`security_unmanaged`, or from loading | ||
| untrusted ``.mpy`` files (see :ref:`security_mpy`), are generally not treated as vulnerabilities in |
There was a problem hiding this comment.
I've performed complete in-place MicroPython -> pure C / Pico SDK field migrations with .mpy (native C modules) so it might be worth being clear here (saving people a click) that .mpy can contain compiled C hitting raw registers and, short of an MMU and on-chip security, is basically game over with fundamentally no mitigation short of disabling it altogether.
There was a problem hiding this comment.
Good point, I've added a line saying that outright so people don't have to click through.
| Third-party code | ||
| ~~~~~~~~~~~~~~~~ | ||
|
|
||
| Issues originating in third-party code vendored under ``lib/`` (eg mbedtls) or in a vendor SDK (eg |
There was a problem hiding this comment.
Would it be appropriate to explicitly list the third party modules and where to report security issues? I don't think there are so many that a table couldn't cover our bases.
There was a problem hiding this comment.
I'd rather not keep a list in the docs if we can avoid it, it'll go stale as libs get bumped or swapped. @mattytrentini is working on SBOM generation (with a vulnerability scan against it) and I'm working on some SAST tooling, so the goal is for the included libraries and their versions to come out of the build itself. Once that lands we can just link to it from here.
There was a problem hiding this comment.
Preview the sbom/vulnerability check here:
https://github.com/mattytrentini/micropython/actions/runs/35806345301
| 2. Triage it, confirming the issue, determining affected versions and assessing severity, then share | ||
| our assessment with you. | ||
| 3. Develop and review a fix in the open for public reports. For reports handled privately, keep | ||
| details confidential while a fix is prepared where appropriate. |
There was a problem hiding this comment.
keep details confidential while a fix is prepared where appropriate.
Is the fix prepared where appropriate or the details kept confidential where appropriate? What is and isn't appropriate?
There was a problem hiding this comment.
Yeah that was ambiguous, reworded.
| details confidential while a fix is prepared where appropriate. | ||
| 4. Publish the fix and, where warranted, request a CVE. | ||
|
|
||
| Security reports normally remain on the public issue tracker under the `security |
There was a problem hiding this comment.
I would link on the public issue tracker under the security label or similar, not just the one, ambiguous word- larger tap target, scan-readable.
| Credit | ||
| ~~~~~~ | ||
|
|
||
| We credit reporters with the published fix or CVE unless you ask us not to. We do not run a paid |
There was a problem hiding this comment.
Buried the lede a little here?
There was a problem hiding this comment.
Yep, flipped it around.
| Supported versions | ||
| ------------------ | ||
|
|
||
| Security fixes are applied to the latest release and the current development branch. MicroPython |
There was a problem hiding this comment.
Is there a policy or mechanism for notifying downstream vendors? Or is that the purpose of the CVE.
Not sure this is the right place to mention it, but if the issue affects a vendor's board there's no specific indication about if or where they might be brought into the loop. Perhaps a paragraph in "Guidance for product developers"?
There was a problem hiding this comment.
There isn't one at the moment, beyond the CVE and the public issue. I've added a bullet to the product guidance on where fixes get published, and that we may bring in a port's maintainers or vendor on a private report that affects them. Any stronger commitment than that is probably up to @dpgeorge.
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| The following features give Python code direct access to memory, flash or machine code. The VM does | ||
| not check what this code does, so it can corrupt memory in the same way C code can. Code that uses |
There was a problem hiding this comment.
I think corrupt is selling it a bit short here and implies arbitrary memory access is a side-effect and not the intended outcome of these methods.
There was a problem hiding this comment.
Agreed, reworded.
| All changes are submitted as pull requests and reviewed before merge, including for memory handling | ||
| and untrusted input. CI runs the test suite under AddressSanitizer and UndefinedBehaviorSanitizer on | ||
| the unix port for core changes (see ``.github/workflows/`` for the current set of checks). The | ||
| project does not currently run continuous fuzzing. |
There was a problem hiding this comment.
Does Octoprobe have any bearing on this?
There was a problem hiding this comment.
Not directly, Octoprobe is hardware-in-the-loop testing rather than a security check. It's still useful for catching regressions on real boards, but I didn't want the policy to claim more than the project currently runs.
Documents vulnerability reporting, scope, response targets, CVE handling, the security model, and the release and versioning policy. Signed-off-by: Andrew Leech <andrew@alelec.net>
Points to the security policy in the docs and the reporting channels. Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
f1d45ae to
e9a826d
Compare
Good call, I've moved the scope to the top of the page and added the tools (mpremote etc) to it. For infrastructure like the website and the mip index I'm not sure where reports should go. @dpgeorge would you prefer email, an issue, or a discussion for those? I can add a line to the scope once that's decided. To everyone here thanks for the quick feedback so far, I think the improvements are really great. |
|
Uh... for our new OTA system, we're up to this much coverage. https://github.com/openmv/openmv-ota/tree/main/docs/compliance From our perspective, we generate an SBOM across all repos of micropython and look for CVE's automatically. So, issues just need to be reported and then they will be picked up and any user of the software will be notified. |
This proposes a security policy for MicroPython as a page under
docs/develop/, plus a short release/versioning page.SECURITY.mdis kept to a pointer to the policy and the reporting channels, the same way CPython's points at its devguide.The wording, targets and mechanisms are all open for discussion, as well as the items under "Open questions", and I'd appreciate feedback on any of it.
My aim here has been to mostly formliase what's already done here, with the addition of a CVE policy.
Security issues are reported through the existing
securityissue form and fixed in the open. For reports that are readily exploitable, high impact or otherwise need confidentiality, the policy points reporters at GitHub's private vulnerability reporting, withcontact@micropython.orgas the fallback for anyone who can't use GitHub. Reports have a seven-day acknowledgement target, and privately handled reports have a target embargo of at most 90 days. All of these are stated as best-effort, not guarantees.The policy also sets out what to include in a report, which features bypass memory safety (
machine.mem*, native/viper, inline asm, native modules, raw flash access), and how CVEs are handled. CVEs are requested from the GitHub security advisory workflow, which assigns them under GitHub's own CNA. Dependency defects (mbedtls, ESP-IDF etc) normally keep the upstream CVE unless the MicroPython integration creates a separate issue. CVEs are only assigned against tagged releases,-previewbuilds don't get them.The policy page also documents the trusted
.mpybytecode boundary and the sanitizer checks run on the C runtime. The release and versioning page states the existing1.xcompatibility aim, theMICROPY_PREVIEW_VERSION_2path for breaking changes and the single-release-line support model.The security issue form stays, with its version instructions fixed to point at the startup banner shown after boot or a
Ctrl-Dsoft reset.If this is accepted / merged I'd like to (personally) follow this up by an activity to review past issues / code changes for anything that (in hindsight) meet agreed-on criteria for a CVE and raising them (after suitable review) to backfill the record.
While it will be clearly visible that these were done after the fact I believe it will serve as evidence that important fixes have historically been found and fixed in an appropriate way, regardless of whether they were publicly discussed through the CVE system. I've heard from some people in the cybersecurity space that not having a "regular stream" of CVE's over the years is sometimes seen as a lack of maturity rather than a sign of stability.
Part of the motivation for this all now is the EU Cyber Resilience Act. The CRA obligations fall on the manufacturers who ship products, and open source developed outside a commercial activity isn't directly in scope (Espressif's March 2026 ESP32 CRA guidance takes the same view for the framework layer). MicroPython makes no guarantees and isn't responsible for products built on it. That being said, people building products on MicroPython need a clear place to report issues, a record of CVEs and fixes, and a stated security model to point at in their own CRA documentation. This PR is MicroPython doing its part there, on a best-effort basis.
Proposed micropython.org/security page
The website isn't in this repo, so I've attached a mockup of a matching front-door page for micropython.org. It links out to the docs pages rather than repeating them, and uses the same channels and targets. It's modelled on zephyrproject.org/security but leaves out the downstream product-maker notification list, since MicroPython doesn't run one.
website-security-page-mockup.html
Open questions
Enabling private vulnerability reporting
If this is accepted, private vulnerability reporting will need enabling on micropython/micropython and micropython-lib, as it's currently off on both. It's a repo admin setting under Settings > Security (Code security and analysis on some layouts).