# Security policy

## Private reporting

Report vulnerabilities through [GitHub private vulnerability reporting](https://github.com/jagaliano/whatsapp-ng/security/advisories/new), which is enabled for this repository.

Do not put credentials, QR codes, auth directories, API keys, phone numbers, private message bodies or unredacted logs in public issues. Provide a minimal synthetic reproduction, candidate commit/version and relevant Pi/Node/OS versions. Do not attach real auth or conversation archives, even to a private report.

Ordinary non-sensitive bugs belong in [issues](https://github.com/jagaliano/whatsapp-ng/issues). Maintenance and responses are best effort, with no SLA.

## Release scope and limitations

The maintainer approved stable `whatsapp-ng@1.1.0` under `latest` on October 29, 2026, promoting the prepared RC2 source without additional runtime/dependency changes. Stable labeling does not add an SLA, erase the findings below or certify untested clients/platforms. The prior RC2 [consolidated source/evidence record](https://github.com/jagaliano/whatsapp-ng/blob/main/specs/040-speech-and-settings/evidence.md) remains dated; the [stable 1.1.0 changelog entry](https://github.com/jagaliano/whatsapp-ng/blob/main/CHANGELOG.md#110--2026-10-29) records the new authorization and unchanged acceptance boundaries.

Development targets Node 26.x and Pi 1.4.0. The dated October 27, 2026 macOS source checkpoint passed **1101 tests/78 files**, with two workers and no skips, plus lint/typecheck; it is not the current RC2 artifact qualification. See the [RC2 source/evidence record](https://github.com/jagaliano/whatsapp-ng/blob/main/specs/040-speech-and-settings/evidence.md) for later checks and explicit remaining scope. Tesseract 5.5.3 and LiteParse 2.17.0 local raster/scanned-PDF OCR were already validated on **October 24, 2026**, and those real-tool checks passed again at that source checkpoint. English/Spanish data availability is not a general recognition-accuracy guarantee. Earlier Linux package tests used Pi 1.3.0 and do not establish support for the updated package. Live evidence includes a user-confirmed Groq-to-Fish self-chat voice note and separate complete English/Spanish Edge synthesis; Edge WhatsApp playback, Windows, service installers and broader group/history/receipt behavior remain unverified.

Remote STT is an explicit opt-in through `sttEndpoint`, `sttModel` and `sttEnv`. This uploads admitted WhatsApp voice-note audio to the configured provider; disclose that data flow to trusted chat participants and review the provider's retention/billing policy. `sttEnv` is only the key's environment-variable name; never put an API key in that field or an endpoint URL. STT and TTS require HTTPS except for loopback HTTP (127.0.0.0/8, localhost, [::1]) or an explicit `WHATSAPP_NG_ALLOW_PLAIN_HTTP=1` in Pi's launch environment. Non-loopback HTTP exposes audio, reply text and any Bearer key without encryption; the flag is not participant consent or server authentication. The flag applies process-wide to both clients, not one host. Removing it makes stored non-loopback HTTP invalid again; invalid saved TTS pauses automatic text replies as well as speech. Originals are retained: restore the deliberate launch environment and restart Pi for non-destructive recovery. The in-app Voice Reset instead clears backend, consent and per-chat reply/speech overrides; it is not endpoint-only repair. Remote requests still reject embedded credentials, query strings/fragments and redirects; errors omit provider bodies/headers. File/response bounds, timeouts and best-effort session cancellation do not retract audio already uploaded. New private audio scratch files are removed after normal success/failure, but abrupt process termination can leave them behind. Local CLI preparation/transcription is bounded to ten minutes, cancelled on session change, and waits for child closure before scratch cleanup; the native addon does not have that child-process cancellation guarantee. Incoming image/video/document downloads are capped at 25 MiB. Newly created download directories/files use `0700`/`0600` and exclusive unique filenames; existing files and directory permissions are not retroactively changed. Existing archives and Pi conversations still retain transcription text under the normal shared-context policy. Tests include a synthetic speech upload and a real WhatsApp voice note transcribed through Groq. These limited checks do not establish general recognition quality, compatibility with other providers or all WhatsApp routing behavior. See [audio configuration](README.md#audio-transcription) and the [local speech guide](docs/crispasr.md).

Speech synthesis sends eligible final-answer text to the configured speech provider, separately from STT's audio upload. It stays off until explicitly enabled with destination-specific consent in terminal `/whatsapp` → Voice; groups require their own opt-in. `ttsEnv` is a key-variable name, not a key value. `configure_wa_tts` requires verified local/owner provenance and changes backend configuration only: it cannot grant consent, enable speech or synthesize immediately. Global modes apply across eligible chats without overrides; use a chat-specific setting when only one conversation should speak. Paused chats do not replay old automatic replies on re-enable.

Edge uses the unofficial `speech.platform.bing.com` synthesis transport with exact `msedge-tts@2.1.1`. Its bounded English/Spanish synthesis checks passed, closing the local compatibility gate, not establishing an Azure SLA or permanent availability. Old-endpoint consent is not reused: restart the owning Pi before selecting the updated Edge backend and approve its new destination explicitly. The fixed-phrase preview needs its own exact-recipient confirmation and does not enable ongoing speech. Already-started uploads cannot be recalled; uncertain sends are not automatically repeated. See [speech configuration and limits](README.md#speech-replies-opt-in).

Optional tool-image projection and terminal-answer forwarding are off by default and require explicit terminal **Optional outputs** confirmation. Approved tool images may reveal private screen/workspace information to the verified owning WhatsApp chat. Only actual inline image results are eligible; file paths/URLs in text or details do not authorize uploads. Terminal/RPC final text may contain workspace information and goes only to the consented private owner/account, not a group, last chat or gateway redirect. No raw thinking/tool-result streams or terminal screenshots are automatically projected. Enabling midway cannot export prior work, but already-issued sends cannot be recalled; sent text follows ordinary WhatsApp history retention. The owner confirmed a bounded private terminal-forwarding/disable test; automatic-image live behavior remains unverified beyond isolated source/native tests. See [C3 scope](specs/039-extension-improvements/c3-validation.md).

New extension diagnostics are metadata-only, including in verbose mode; raw speech/native-error payloads are not printed. The private `whatsapp-ng.runtime.log` uses best-effort 5 MiB rotation plus one backup, whose older contents are replaced on rotation. Historical `whatsapp-ng.log` and unrelated data are not removed or retroactively redacted. Already retained logs may contain private content. The narrow known-libsignal-noise filter does not blanket-mute ordinary application errors. See [settings and log privacy](README.md#settings-off-and-diagnostic-privacy). No new live-client logging certification is claimed.

All allowed chats share one Pi context. The owner guard is a control-plane policy, not a sandbox for Pi's other coding tools. This is a trusted-user extension, not a multi-tenant privacy boundary. Retained data contains conversation content; filesystem permissions are not encryption at rest.

Baileys is an unofficial personal-account transport. Protocol changes, platform policies, account restrictions and upstream security defects remain risks. Use one active extension/process per auth profile. A separate transport lease and retired-auth I/O fences protect cooperating same-profile clients; archive locking alone does not. Old/uncooperative clients, cloned credentials and distributed/network-filesystem locking remain outside that guarantee. Stop previous clients before switching.

Auth adoption occurs only during requested connection under source/destination ownership, never as an offline-history side effect. Initialized profiles are not merged; legacy originals remain preserved. Private non-secret profile metadata blocks re-adoption after reset and implicit recovery from interrupted/unsupported state. Auth directories are `0700`; saved credentials/config/control files and archive snapshots are `0600`. Native key-file leaf modes may follow the umask, so their private directory is the confidentiality boundary. The pinned multi-file store is not a transactional database; individual file failures are not an automatic credential rollback or repair guarantee. See [auth recovery guidance](README.md#auth-adoption-and-recovery).

Dependency updates removed vulnerable PDF-processing and outdated development-tool dependencies, but known Pi SDK/host findings remain. The **October 31 release 1.1.2 source refresh** reports zero production findings after the explicitly approved `follow-redirects` 1.16.1 → 1.16.2 lock refresh. Existing consumer locks still need separate audit/refresh. The full tree reports twelve affected development packages (one high, eleven moderate), including the eight Undici advisories and newly reported Minimatch globparts amplification. The earlier October 30 assessment had two affected packages; dated details remain in DEPENDENCIES.md. This is not a new installed-host/bundled-code reassessment; production-only auditing excludes host-supplied packages and does not certify native binaries. The project is waiting for a patched Pi release and upstream lint-tooling releases for Minimatch; no local override, audit suppression or forced SDK downgrade has been applied. These findings are not resolved or certified harmless. See [DEPENDENCIES.md](DEPENDENCIES.md) for dependency versions, retained GPL components and audit details, and [LICENSING.md](LICENSING.md) for attribution.

If a session appears compromised, stop the extension/services and review linked devices through WhatsApp. Do not publish sensitive evidence or delete/migrate state automatically as a recovery procedure.
