# Security Policy

## Reporting a Vulnerability

Please report security vulnerabilities through GitHub's [private vulnerability
reporting](https://github.com/DelSkayn/rquickjs/security/advisories/new)
feature, **only if** your report meets the rules below. Reports that do not
meet these rules should be filed as regular public issues instead.

## Scope

rquickjs provides safe, high-level Rust bindings to the QuickJS-NG engine. This
policy covers bugs **in the bindings**: unsoundness in the safe API, incorrect
`unsafe` at the FFI boundary, memory-safety issues reachable without writing
`unsafe`, and mistakes in features rquickjs itself implements (data conversion,
class registration, module loaders/resolvers, allocators, the `embed` macro,
async integration).

### In scope

- **Soundness holes:** any way to trigger undefined behavior, memory
  corruption, or a data race from **safe** Rust using only the public API. A
  safe wrapper that allows UB without `unsafe` is a bug in rquickjs.
- **Incorrect FFI assumptions:** lifetime, ownership, or invariant mismatches
  between the Rust layer and the C engine that lead to use-after-free, double
  free, or out-of-bounds access.
- **Wrapper logic errors** in conversion, class binding, `Trace`/GC integration,
  loaders, or the `embed`-generated bytecode path.

### Out of scope

- **Bugs inside the QuickJS-NG engine itself.** Crashes, memory corruption, or
  sandbox escapes originating in the C engine (reachable from untrusted JS
  source) should be reported upstream to
  [quickjs-ng/quickjs](https://github.com/quickjs-ng/quickjs/security). If a
  fix requires changing engine C code, it is upstream's issue, not rquickjs's.
- **Bytecode hardening.** QuickJS bytecode is not designed for adversarial
  input. Loading untrusted bytecode (including via the `embed` macro or
  `JS_READ_OBJ_BYTECODE`) is equivalent to executing untrusted native code.
  Only load bytecode you produced yourself or obtained from a trusted source.
- **Misuse of `unsafe` APIs by the caller.** rquickjs exposes some `unsafe`
  functions with documented invariants; violating those invariants is caller
  error, not a vulnerability.
- **Untrusted C API input passed through raw handles**, or anything that
  requires the embedder to already be compromised.

## Rules for Private Reports

Private reporting exists to protect users from issues an attacker could not
otherwise discover.

**AI-detected bugs are by definition not secret.** If a publicly available tool
found a bug by reading our public source, anyone else running the same tool
will find the same bug. File those as public issues, where duplicates are
visible and the fix discussion is shared. AI tools are welcome, but use them to
add value: read the code, confirm the bug, write a patch, write a test. A
drive-by forward of a tool's raw output is not a useful report.

Before submitting a private report, ensure all of the following:

- **You have manually verified the bug.** You understand the code path,
  confirmed the issue is real, and can explain it in your own words.
- **You have a working reproducer.** Attach a minimal reproducer — ideally a
  small Rust program using **only safe** rquickjs APIs (or a short snippet
  showing the exact `unsafe` invariant that is unsound) that triggers the bug
  on a recent `master` commit. Note the rquickjs version and the QuickJS-NG
  submodule commit.
- **Impact is concrete and verifiable.** State what actually happens (e.g.
  "use-after-free reachable from safe code via `Ctx::…`"), not speculative
  consequences.
- **The report is concise and in plain text.** Lead with the affected module,
  function, and the invariant that breaks. No multi-page write-ups or severity
  tables.
- **The threat model matches rquickjs.** The bug must be a soundness or
  memory-safety defect in the bindings, triggerable without the caller writing
  incorrect `unsafe`. Engine-internal bugs and bytecode issues are out of scope
  (see above).
- **A proposed fix is welcome, and must be tested.** A patch should compile,
  pass `cargo test` (including under Miri where applicable), and include a
  regression test.

Reports that do not meet these rules may be closed without detailed response
and asked to be refiled publicly.

## RustSec / Advisories

Confirmed, released soundness or memory-safety issues in the bindings will be
published as GitHub Security Advisories and, where they meaningfully affect
downstream crates, submitted to the [RustSec Advisory
Database](https://rustsec.org). We generally will **not** request advisories
for issues that require `unsafe` misuse by the caller, engine-internal bugs
(track those upstream), or findings already discoverable from the public commit
history by the time the report arrives.
