Skip to content

Add security policy and supporting documentation - #19722

Open
andrewleech wants to merge 3 commits into
micropython:masterfrom
andrewleech:security-policy
Open

andrewleech wants to merge 3 commits into
micropython:masterfrom
andrewleech:security-policy

Conversation

@andrewleech

@andrewleech andrewleech commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

This proposes a security policy for MicroPython as a page under docs/develop/, plus a short release/versioning page. SECURITY.md is 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 security issue 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, with contact@micropython.org as 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, -preview builds don't get them.

The policy page also documents the trusted .mpy bytecode boundary and the sanitizer checks run on the C runtime. The release and versioning page states the existing 1.x compatibility aim, the MICROPY_PREVIEW_VERSION_2 path 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-D soft 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

  • CVE route. GitHub's CNA already covers repositories without their own CNA and needs no application, which is why the policy uses it. The alternatives are partnering with another CNA or becoming a CNA, and I don't think either is worth it at the current CVE volume.
  • CRA support periods. Manufacturers are expected to support CRA products for around five years from market placement, so some may ask for a defined support or LTS commitment rather than "track the latest release". This PR doesn't change the single-release-line model, however it's the obvious place that pressure would land.

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).

Comment thread docs/develop/security.rst
``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).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the list not also include direct flash modification? Some ports provide an API.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, added.

Comment thread docs/develop/security.rst Outdated
Scope
-----

This policy covers the MicroPython core (``py/``, ``extmod/``, ``shared/``), the maintained ports

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend that all micropython-lib modules are also explicitly included, whether they are actually frozen in a standard firmware, or mip-installed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/develop/security.rst Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rst formatting not correct

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It renders as a normal link in the built docs,

I was indeed trusting the GH .rst preview

Comment thread docs/develop/security.rst Outdated
Leaving the managed subset
~~~~~~~~~~~~~~~~~~~~~~~~~~

The following documented mechanisms deliberately leave the managed subset and carry the same

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah fair, that term was doing more harm than good. I've reworded the section without it, see if that reads better.

Comment thread docs/develop/security.rst Outdated
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also mention loading .mpy modules from ROMFS that are deployed through mpremote+mpy-cross , are they less trusted than frozen .mpy modules ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Josverl

Josverl commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Thanks for putting this together,
I think it is a good to clarify these things.

@Gadgetoid

Gadgetoid commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Possibly worth some note about how to report security issues with the surrounding ecosystem and tooling of MicroPython, since it launches straight into The affected version (shown in the startup banner... which is very MicroPython - the device firmware - specific and proffers no information about how to report (quite probably much more critical) infrastructure issues. Just listing what is and isn't in the scope of the security policy up front might help- with links out to the appropriate places to report anything else (if there are such places)

Me - reading "Guidance for product developers" - aah yes, I do none of that 😭 Almost by necessity, mind.

Comment thread docs/develop/security.rst Outdated
* 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be easier just to say A minimum reproducible example pasted directly into the report.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done.

Comment thread docs/develop/security.rst Outdated
<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,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done. Good point about frozen code too.

Comment thread docs/develop/security.rst Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this still holds given the amendment above, this contradiction becomes a clarification.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, reads better now.

Comment thread docs/develop/security.rst Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I've added a line saying that outright so people don't have to click through.

Comment thread docs/develop/security.rst Outdated
Third-party code
~~~~~~~~~~~~~~~~

Issues originating in third-party code vendored under ``lib/`` (eg mbedtls) or in a vendor SDK (eg

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread docs/develop/security.rst Outdated
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that was ambiguous, reworded.

Comment thread docs/develop/security.rst Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done.

Comment thread docs/develop/security.rst Outdated
Credit
~~~~~~

We credit reporters with the published fix or CVE unless you ask us not to. We do not run a paid

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buried the lede a little here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, flipped it around.

Comment thread docs/develop/security.rst
Supported versions
------------------

Security fixes are applied to the latest release and the current development branch. MicroPython

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/develop/security.rst Outdated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, reworded.

Comment thread docs/develop/security.rst
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Octoprobe have any bearing on this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@andrewleech

Copy link
Copy Markdown
Contributor Author

Just listing what is and isn't in the scope of the security policy up front might help- with links out to the appropriate places to report anything else (if there are such places)

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.
@kwagyeman on the chance you've been looking into the CRA and related from an openmv perspective I'd be interested in any of your learnings too and what if anything on the micropython side would help support there too (as another company acctively shipping products with micropython inside).

@kwagyeman

Copy link
Copy Markdown
Contributor

Uh... for our new OTA system, we're up to this much coverage.

https://github.com/openmv/openmv-ota/tree/main/docs/compliance
https://github.com/openmv/openmv-ota/blob/main/docs/compliance/cra-red-alignment.md
https://github.com/openmv/openmv-ota/blob/main/docs/compliance/residual-threats.md

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.

@projectgus
projectgus self-requested a review September 30, 2026 03:45
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.

6 participants