Files
PX4-Autopilot/SECURITY.md
Julian Oes f5586139e4 feat(security): define security scope (#28571)
* docs(mavlink): present link encryption alongside message signing

The hardening guide told integrators that production deployments must
enable message signing, presenting it as the only way to secure a MAVLink
link. Encrypting the link below MAVLink, with an encrypted radio, a VPN or
IPsec, is at least as strong: it uses standard, reviewed cryptography, it
gives confidentiality as well as authentication, and it covers every
interface on the link rather than only MAVLink.

Present both options, and reword the passages that assumed signing was the
only one.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

* docs(security): develop security fixes in public pull requests

Record that fixes are developed as ordinary public pull requests, with no
private forks and no embargoed branches.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

* docs(security): add security scope document

Describe the boundary the code implements today: what PX4 protects, what it
assumes about the layers beneath it, what the shipped default does and does
not do, and two lists for what is always in scope and what is out. It
describes the boundary rather than pre-deciding reports. A finding that fits
neither list stays a judgement call that maintainers make on the report.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

* docs(security): list a security maintainer for report triage

Security report triage had no named owner, so an unacknowledged report had
nowhere to go except the release managers. Add a Security block to the
maintainers list, and point the follow-up path in SECURITY.md at it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

* docs(mavlink): note that the first signing key is unauthenticated

The guide already says to provision over a trusted link, and the info box says
that changing or disabling a key requires a signed message. It does not say that
setting the first one cannot, since there is no key to sign with yet, so a reader
can come away believing provisioning itself is protected.

Say plainly that the window exists, what an attacker gets from it, and how to
recover.

Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: Julian Oes <julian@oes.ch>

* Apply batched suggestions from code review

Co-authored-by: Sheren N <sherenyn@ad.uni-paderborn.de>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Julian Oes <julian@oes.ch>

* feat(security): more review fixup

* fix(security): only 1.18 gets security bugfixes

* fix(security): link to SECURITY_SCOPE

* fix(securiy): small wording fixups

* docs(security): scope by attacker position, not bug class

The "Always in scope" list made any memory corruption, race or hang a
vulnerability regardless of who can reach it. That is not how reports
have been handled: sanitizer runs in SITL have found and fixed many
such bugs as ordinary PRs, and a peer on an unsecured link already has
a shell.

Replace it with one test: a finding is a vulnerability when it gives
capability to an attacker who has neither the operator's access nor
physical access. Keep the in-tree board configuration rule, point to
the sanitizer docs, and fix two typos.

Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: Julian Oes <julian@oes.ch>

* fix(docs): formatting

* fix(maintainers): add Ramon to security as well

* docs(security): draw the boundary as a mermaid diagram

GitHub renders mermaid natively, so the boundary diagram no longer has to
be maintained as hand-aligned ASCII. Label the two zones with the wording
of the sentences below it, so the picture and the prose say the same
thing.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

* fix(docs): review fixups

* docs(security): say how to isolate the offboard transports

A direct cable between flight controller and companion is not enough on
its own: the agent or router republishes into the DDS or Zenoh network
on the companion, so that network is inside the boundary too.

Keep the scope document to what is inside the boundary and put the
isolation advice next to the uXRCE-DDS and Zenoh setup instructions.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

---------

Signed-off-by: Julian Oes <julian@oes.ch>
Co-authored-by: Sheren N <sherenyn@ad.uni-paderborn.de>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-09-21 10:49:01 +12:00

7.2 KiB

Security Policy

Supported Versions

The following versions receive security updates:

Version Supported
1.18.x
< 1.18

Reporting a Vulnerability

We receive security vulnerability reports through GitHub Security Advisories. If AI assistance contributed to your finding, do not file a private advisory: read AI-Assisted Discovery instead.

Before filing, check the finding against SECURITY_SCOPE.md, which describes where PX4's security boundary sits and what is in scope. Most memory-safety bugs, races and hangs are not vulnerabilities, because they are only reachable from a position that already has the operator's access. Fix those with a pull request, or open an issue.

To begin a report, go to the PX4/PX4-Autopilot repository and click on the Security tab.

Click Report a Vulnerability to open the advisory form. Fill in the advisory details form. Make sure your title is descriptive and the description contains all relevant details needed to verify the issue. We welcome logs, screenshots, photos, and videos.

At the bottom of the form, click Submit report.

Response Process

  1. Acknowledgment: The maintainer team will try to acknowledge your report within 7 days.
  2. Triage: We decide scope against SECURITY_SCOPE.md, assess severity and impact, and communicate next steps.
  3. Fix: The fix is developed as a normal pull request against main, in the open. See How Fixes Are Developed.
  4. Release: The fix is public once the pull request is merged. Where it applies to a supported release branch it is backported, and it appears in the release notes. If a report warrants a published advisory or a CVE, we publish it through GitHub and credit the reporter unless they request anonymity.

If you do not receive acknowledgment within 7 days, please follow up by emailing the security maintainers or the release managers listed in MAINTAINERS.md.

How Fixes Are Developed

Security fixes are developed as ordinary public pull requests. We do not use private forks or embargoed branches.

This is a deliberate choice because downstream users do not update quickly enough for a coordinated release date to protect them, and many are not tracking upstream closely at all. Development in a private fork means fewer reviewers and no CI checks, which can cause issues once merged.

The pull request makes the existence of the bug public, and that is expected.

Keep the reproducer out of it: it works against vehicles in the field until the fix has shipped and been adopted. If you reported through the Security tab, the reproducer is already in the advisory and maintainers have it, so there is nothing further to send. Describe the demonstrated impact in the pull request and leave it at that.

If you are reporting a bug you cannot fix yourself, report it privately first, through the process above, and maintainers decide when it moves to a public pull request. The exception is AI-Assisted Discovery, which goes public from the start.

AI-Assisted Discovery

We align with the Linux kernel security policy on AI-assisted bug discovery.

If you used AI assistance to identify a bug, treat it as public. You may have good reasons to believe it is not, but both the kernel security team and PX4 maintainers have seen bugs found this way surface across multiple researchers at the same time, often on the same day. So skip the private advisory and go straight to a pull request with a fix. If you cannot submit a fix yourself, first search the open pull requests for one that already addresses it; only if nothing exists, open an issue.

The rules on reproducers in How Fixes Are Developed apply here too: the pull request is public, the reproducer is not.

Responsible Use of AI to Find Bugs

A growing share of incoming security reports comes from AI-assisted code review. It can surface real bugs in rarely exercised code, but it also floods maintainers with reports. If AI tooling contributed to your finding, the guidance above applies, and so do the following points:

  • Length: Lead with a short summary: the affected module or file, the affected versions, and the demonstrated impact. AI tools tend to produce pages of sections and filler. Configure yours to write a concise, human-style report. Triage should never require scanning pages of text to find the essential facts.
  • Signal over noise: Skip boilerplate sections and decorative structure that bury the facts. State only what you have demonstrated, in concrete PX4 terms: what an attacker on the MAVLink link, RC link, or CAN bus can actually do, such as write a parameter, change flight mode, arm the vehicle, or upload firmware. Do not enumerate speculative consequences.
  • Reproducer: Have your tool produce a reproducer and test it yourself. A reproducer that works against SITL (make px4_sitl) is the gold standard. If it does not work, or the tool cannot produce one, treat the report itself as suspect. As stated above, do not post the reproducer publicly. Mention that it exists and share it with maintainers on request.
  • Propose a fix: AI tools are often better at writing code than judging it. Have your tool propose a fix and test it before you report: in SITL at minimum, on hardware if the code path requires it. If the fix cannot be tested because it depends on hardware nobody has, the issue is likely not a real security bug. Fixes must follow the contribution guide.

Reports that disregard these points risk being ignored.

Use common sense before filing. If the affected code is a driver for a discontinued board or a rarely used peripheral and has not been touched in years, exposed users are probably close to zero and the report is not worth a maintainer's time. If the issue is trivial and publicly discoverable, take it straight through the flow above: a public pull request, or an issue as a last resort.

Secure Development Practices

The PX4 development team applies the following practices to reduce security risk:

  • Code review: All changes require peer review before merging.
  • Static analysis: clang-tidy runs on every pull request with warnings treated as errors.
  • Sanitizers: SITL can be built with AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer to find memory-safety bugs and races.
  • Fuzzing: A daily fuzzing pipeline using Google fuzztest tests MAVLink message handling and GNSS driver protocol parsing.
  • Input validation: All external inputs (MAVLink messages, RC signals, sensor data) are validated against expected ranges before use.
  • Compiler hardening: Builds use -Wall -Werror, stack protectors, and other hardening flags where supported by the target platform.