@@ 8,9 8,9 @@ I try to accommodate everyone's workflow. Here's ways to contribute and how, in
### Security vulnerabilities, non-public contact
-If you want to connect with me directly: my email address is at the bottom of the man pages or in the commit logs. Vulnerability disclosures should be PGP-encrypted using the PGP key [1E892DB2A5F84479](https://seirdy.one/publickey.asc).
+If you want to connect with me directly: my email address is at the bottom of the man pages or in the commit logs. Vulnerability disclosures should be PGP-encrypted using the PGP key [1E892DB2A5F84479](https://seirdy.one/publickey.asc). Alternatively, send an encrypted message on Matrix to `@seirdy:envs.net`
-Alternatively, send an encrypted message on Matrix to `@seirdy:envs.net`
+Refer to [`doc/SECURITY.md`](https://git.sr.ht/~seirdy/moac/tree/master/item/doc/SECURITY.md) for information on security requirements.
### Bug reports and TODOs
@@ 60,7 60,7 @@ For the library: everything possible should be covered by tests. If a branch tha
That being said, don't write tests just for the sake of ticking off a box. Statement coverage isn't sufficient to show that most/all statements are useful and correct. Other ways to measure test comprehensiveness include branch coverage (see [gobco](https://github.com/rillig/gobco)) and mutation scores (see [go-mutesting](https://github.com/zimmski/go-mutesting)). Should you choose to give these tools a spin (you don't have to), be aware of false positives. I try to keep the mutation score above 0.7 for now.
-For the CLI: this uses [testscript](https://godocs.io/github.com/rogpeppe/go-internal/testscript) to test CLI behavior.
+For the CLI: this uses [testscript](https://godocs.io/github.com/rogpeppe/go-internal/testscript) for scenario tests.
If you want live test feedback while hacking and find the tests to be too slow (they typically take under 3s by default on my low-end notebook), set the environment variable `LOOPS` to something below `64`; running `make test-quick` will set it to `10`. Test-cases for password generation run multiple times because of the non-determinism inherent to random password generation. Tests are a bit slow since `GenPW()`'s tests have thousands of test-cases generated from combinations of possible parameters.
@@ 1,34 1,43 @@
MOAC Security
=============
+Users place a very high degree of trust in password generators and evaluators. MOAC must therefore meet a high bar for security standards.
+
Security requirements
---------------------
-- Password generation is the only source of non-determinism from random-number generation. It exclusively uses CSPRNG offered by the `crypto/rand` package from the Go standard library.
+Security features users can and cannot expect:
+
+- Password generation, the only component that features non-determinism, exclusively uses the CSPRNG offered by the Go stdlib's `crypto/rand` package. Check the GoDoc for `crypto/rand` to see its security standards.
- Entropy measurement is based solely on password length and charsets used; it does not take into account any other characteristics such as dictionary words, repetition, etc. Entropy measurement was designed under the assumption that the measured passwords were randomly generated.
-- Password strength metrics depends only on physical laws, never needing to be updated to account for advancements in computing power.
+- Password strength metrics depend only on physical laws, never needing to be updated to account for advancements in computing power.
- Password-crackability metrics do not assume the presence of a key-derivation function or key stretching/strengthening. Making fewer assumptions helps maintain simplicity and applicability to the widest range of threat models.
-- Simplicity: MOAC should have a limited scope (password analysis and generation) and size (<1k SLOC, excluding tests). This isn't technically a security requirement, but it does keep attack surface low and reduce room for bugs.
+- Simplicity: MOAC should have a limited scope (password analysis and generation) and size (<1k Go SLOC, excluding tests). This isn't technically a security requirement, but it does keep attack surface low and reduce room for bugs.
-Dependencies
-------------
+Third-party dependencies
+------------------------
-- The MOAC library has no third-party dependencies. The CLI utilities' third-party dependencies are limited to official libraries from `golang.org/x/`, a simple `getopts`-like flag parser, and a testing library. Some of these include indirect dependencies that are only used for testing the dependencies and are not included in the final binaries.
-- A CI job scans dependencies against Sonatype's OSS Index on every push.
+MOAC is split into a library and two CLI utilities. The library has no third-party dependencies; the CLI utilities have two direct third-party dependencies and a third one just for tests. A CI job scans these dependencies and indirect dependencies against Sonatype's OSS Index on every push.
Builds
------
-- MOAC should never require any use of C libraries or dynamic linking; binaries can be 100% Go-based (with the exception of OpenBSD, which uses CGO for all Go binaries as of Go 1.16) to ensure a high level of memory safety. Depending on build flags, it's still possible to use CGO (e.g. if using `-buildmode=pie`), but it should never be a requirement.
+- MOAC should never require any use of C libraries or dynamic linking; binaries can be 100% Go-based (with the exception of OpenBSD binaries, which use CGO for syscalls as of Go 1.16) to ensure a high level of memory safety. Depending on build flags, it's still possible to use CGO (e.g. if using `-buildmode=pie`), but it should never be a requirement.
- MOAC supports reproducible builds that contain bit-for-bit identical binaries for a given Go toolchain.
Checks and enforcement
----------------------
-Every push triggers CI jobs that run several tests in VMs
+Every push triggers CI jobs that run several tests in VMs.
- Every reachable, non-deprecated statement in the library should be covered by tests. Mutation testing should reveal a mutation score above 0.7.
-- Password generation is tested especially heavily, with thousands of test-cases assembled from combinations of valid parameters covering known edge cases. Furthermore, each test case is tested 512 times in an OpenBSD VM and 128 times in an Alpine VM due to the non-determinism of password generation.
-- One VM runs tests with Go's memory sanitizer and race detector.
+- Password generation is tested especially heavily, with thousands of pairwise test-cases assembled from combinations of valid parameters covering known edge cases.
+- Furthermore, each pairwise case undergoes gorilla testing to account for the non-determinism of password generation. In CI jobs, this includes 512 repetitions in an OpenBSD VM and 128 repetitions in an Alpine Linux VM.
+- A Fedora Linux VM runs tests with Go's memory sanitizer and race detector enabled.
- Every push undergoes strict static analysis that includes GoKart and every relevant linter in golangci-lint. Check those projects to see which vulnerabilities they cover.
+Support policy
+--------------
+
+MOAC follows a rolling release system, and does not backport fixes to previous versions. Deprecated code may receive security fixes, but won't be held to the same testing standards.
+