Skip to content

Commit ea17fce

Browse files
mschmickingclaude
andcommitted
docs: add a security policy
GitHub's template is a supported-versions table and a placeholder sentence, which tells a researcher nothing. This one names where the risk actually is — credential storage, the path guards that turn server-controlled ids into filenames, the auth and TLS handling — so someone looking has somewhere to start. It also records the deliberate trade-offs so they need not be re-reported: the stored password is a 0600 file rather than encrypted because there is no portable keychain, there is no --password flag because argv is readable via ps, allowSelfSigned accepts any certificate, and push is field-scoped by design. Response expectations are what one person in their spare time can actually meet, rather than an SLA that would be missed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 46518e9 commit ea17fce

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ test -z "$(iob-sync --json status | jq -rc 'select(.state != "in-sync")')"
204204
- **[AGENTS.md](AGENTS.md)** — architecture, wire protocol, safety invariants. Written for
205205
AI coding agents, but the fastest way for a human to understand the codebase too.
206206
- **[CHANGELOG.md](CHANGELOG.md)** — release history
207+
- **[SECURITY.md](SECURITY.md)** — how to report a vulnerability, and the deliberate trade-offs
207208

208209
## License
209210

SECURITY.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Security policy
2+
3+
`iobroker-sync` connects to a live ioBroker instance with credentials and writes files
4+
derived from server-controlled identifiers. Security reports are welcome.
5+
6+
## Reporting a vulnerability
7+
8+
**Please do not open a public issue.** Use GitHub's private reporting:
9+
10+
**[Report a vulnerability](https://github.com/mschmicking/iobroker-sync/security/advisories/new)**
11+
— Security → Advisories → Report a vulnerability.
12+
13+
This is a spare-time project maintained by one person. Realistic expectations:
14+
15+
- Acknowledgement within about a week.
16+
- A fix for anything that exposes credentials or writes outside the script root gets
17+
priority over everything else.
18+
- I will tell you plainly if I think something is not a vulnerability, and why.
19+
20+
Credit in the advisory and the changelog if you would like it.
21+
22+
## Supported versions
23+
24+
| Version | Supported |
25+
| -------------- | ------------ |
26+
| latest `1.x` ||
27+
| anything older | ❌ — upgrade |
28+
29+
Fixes ship as a new release rather than as patches to old versions.
30+
31+
## Where the risk actually is
32+
33+
If you are looking for somewhere to start:
34+
35+
- **`src/credentials.ts`** — password storage. Written to
36+
`~/.config/iobroker-sync/credentials.json`, mode `0600` in a `0700` directory, via
37+
temp-file-and-rename.
38+
- **`src/sync/safe-path.ts`** — server-controlled ioBroker ids become local file paths.
39+
Guards against traversal, symlinked files and symlinked directories.
40+
- **`src/client/auth.ts`** — OAuth2 and legacy login, TLS handling.
41+
- **`src/commands/backup.ts`** — snapshots contain whatever secrets the live scripts do,
42+
and land under the gitignored `.iobroker-sync/`.
43+
44+
## Deliberate decisions that are not bugs
45+
46+
These are known trade-offs, documented so they need not be re-reported:
47+
48+
- **The stored password is not encrypted.** It is a `0600` file in a `0700` directory
49+
outside the project. There is no portable OS keychain across Linux, macOS, Windows and
50+
Termux, and the realistic alternative — an environment variable — is worse: it leaks
51+
into shell history and into the environment of every child process.
52+
- **There is no `--password` flag.** `argv` is readable by any local process via `ps` and
53+
is recorded in shell history. Use `--password-stdin`, `IOBROKER_PASSWORD`, the saved
54+
credential, or the interactive prompt.
55+
- **`allowSelfSigned` accepts any certificate.** It exists because ioBroker refuses
56+
passwords over plain HTTP, so authenticated instances are HTTPS with a self-signed
57+
certificate. There is no certificate pinning; on an untrusted network, that is a
58+
meaningful limitation.
59+
- **`push` cannot disable a script or move it between javascript instances.** It sends
60+
only `common.source` and `common.engineType`, enforced by the type of
61+
`ObjectsApi.extendScript`. This is a safety property, not an oversight.
62+
- **Test fixtures contain password-shaped strings.** All fake — `secret`,
63+
`correct horse battery staple`, `fake-oauth-token`.
64+
65+
## What is genuinely worth reporting
66+
67+
- Anything that writes outside the configured script root.
68+
- Anything that puts a password into a log line, an error message, `argv`, or the project
69+
directory.
70+
- Anything that makes `push` write a field other than `common.source` and
71+
`common.engineType`.
72+
- Anything that lets a malicious ioBroker server cause local code execution or
73+
arbitrary file writes.

0 commit comments

Comments
 (0)