diff --git a/CHANGELOG.md b/CHANGELOG.md index 258a95f..bd9b8bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,24 @@ Notable changes to JevGate. Versions follow [Semantic Versioning](https://semver ## [Unreleased] +- Injection: code that names a deserializer that can build any object is asked whether it loads data another party sends, in Python, Ruby, Java, JavaScript and TypeScript: Python's `pickle`, `marshal`, `shelve`, `jsonpickle` and `yaml.load`, Ruby's `Marshal.load` and `YAML.load`, Java's `ObjectInputStream`, `XMLDecoder`, XStream and SnakeYAML, and node-serialize. Only Django views and PHP `unserialize` were asked before, so a Flask route passing `pickle.loads(request.get_data())` was clear; it is now a review (CWE-502). Other requests are unchanged, so cached answers stay valid. +- File organization: a file of fewer than 250 lines gets at most a note, and a group holding three quarters or more of a file's members is no longer named as the part to move (a consider left naming no group is a note; a review says to split the whole file). Checked by hand on 25 projects, 3 of 32 findings on shorter files were right against 21 of 29 on longer ones; review precision went from 50% to 67% and consider precision from 46% to 71%. No request changes, so cached answers stay valid. +- Sensitive data: an error-detail trace lists the errors the functions it calls create, with their messages, and asks whether the text a response carries describes an internal failure (a database, network, file or library error) or explains invalid input, instead of who raised it. A handler that returns the message its own service raised to explain a missing record (`except LookupError as exc: raise HTTPException(404, detail=str(exc))`) is no longer a review, while one that returns the text of every exception it catches still is. The Choice over which message a function creates carries another error's text is told the same, so passing on such an error's text is the program's own. On 71 projects, 11 of one FastAPI project's 12 wrong reviews became notes or considers and its two wrong considers became notes, as did a local tool's consider about the text of an API error it returns to the user's own agent; only error-detail traces are asked again. +- Sensitive data: an error-detail answer leaning toward a client in a function whose error message carries another error's text is a note ("puts the text of a library or database error into an error message, which may reach a remote client") instead of a consider. Labeled by hand, 1 of 28 such considers outside example code was right: a central handler replaced the text with a generic message, the error was one written for users (Supabase Auth's "Invalid login credentials"), or no remote client read it (a CLI, a desktop app). On 71 projects, 33 considers became notes, 27 of them wrong; five of the right ones were example files whose leaks their route handlers still report. Nothing is asked again. +- Test redundancy: a pair that would be a review ("one adds nothing") is first asked whether each test checks something the other does not, as Ruby pairs already were; if so, it is a consider. Tests of two overloads with equivalent inputs (`writeTo(Path)` and `writeTo(File)`) were reviews. Pairs that read the same apart from their names are not asked. On 31 labeled projects, test-redundancy reviews went from 4 right and 6 wrong to 4 right and none wrong. +- A finding on a file's constants names the constant it is about ("The constant is `WAGTAILADMIN_BASE_URL`.") and points at it, from a Choice asked after the finding, instead of listing every constant of the file: 20 of 23 such findings across 71 projects are now named. +- An error's message is not its leading status code: `HTTPException(500, f"engine error: {e}")` was quoted as "The message is 500.", and the trace asked which message carries another error's text about `500`. +- Access control: a SECURITY DEFINER function that acts only for whoever holds a secret token it looks up by value, such as an invitation or reset token, is not "skipping the caller check": basejump's `accept_invitation` and `lookup_invitation` are no longer reviews. +- Workflows: a job left undecided is asked, in a recheck, which expression of its `run` scripts holds text outsiders write and what code it runs, as Choices that can only clear it. Undecided jobs went from 14 to 7 across 65 projects, with no finding changed. +- Shared logic: copies in a function or type marked deprecated (a `@deprecated` tag, annotation or decorator, `#[deprecated]`, `[Obsolete]`, or a `Deprecated:` comment above it) are not compared, since they go with the next major version: flysystem's deprecated phpseclib 2 adapter was paired with the phpseclib 3 adapter replacing it in 7 reviews and a consider, all wrong. No other project's findings changed across 71 projects. +- Shared logic: copies in test code outside its cases (fixtures, helpers, setup) are at most a consider. Labeled by hand on 25 projects, 13 of 19 such reviews were a level too strong, while 11 of 12 considers were right as they were; reviews are now for duplicated application code. +- Comments: a Laravel application's `config/*.php` files (an `artisan` script at the root) are not read for comments, since the framework and its packages publish them with their documentation: on two Laravel apps all six comment considers there were the publisher's text, and 14 files' comments stayed undecided. +- A file whose parse holds a few small syntax errors (at most three regions, an eighth of the source) is judged apart from the definitions that hold them, instead of being skipped: tree-sitter's grammars miss some valid code, which left four of zustand's store files and govwa's `user/user.go` unjudged (its MD5 password hashing is now a review). Generator templates (under `templates/`, or with ERB tags or `//#if` conditions) are still skipped. +- Go: a file reaches the other files of its package (its directory) and the packages its `import ( … )` block names, as Java files reach their package. Callers, callees and the files that use a file were missed in Go: an injection's recheck with its callers was never asked, so govwa's SQL injection through a query helper stayed a consider; it is now a review, and callers cleared two notes elsewhere. Only Go projects' requests change. +- Injection: XML parsed with a parser that can resolve external entities (CWE-611) is asked about where the code names such a parser (lxml, SAX, pulldom, DocumentBuilderFactory, XmlDocument, SimpleXML, libxmljs, Nokogiri) or its file imports one and it calls a parse method. pygoat's XXE lab went from a note to a review; across 65 projects only 6 requests changed. +- Java, Kotlin, Scala and Groovy packages named `example` or `demo`, such as Spring Initializr's default `com.example.demo`, are source, not example code: every finding of such a project was capped (injection and sensitive data at a consider, the rest at a note) and its hardcoded values were not judged. Directories above the source root, such as `examples/`, still mark example code. +- A rule can be named by its ID without the group (`--rule file-organization`, `jevgate: allow(sensitive-data) …`, `[rules]` in `jevgate.toml`), besides its full ID and its key; `jevgate.schema.json` lists these names, and an unknown name points to `jevgate rules`. +- Counts in messages are singular or plural ("1 new review finding", "2 files") instead of "finding(s)", including the gate's reasons in the JSON report. - `--dry-run` plans the files whose purpose the cache already answers, as a run does, so a warm cache's estimate matches the run: on a Rails project it counted 106 of 1,532 requests as new while the run sent none. ## [0.19.0] - 2026-09-25 diff --git a/docs/classification-cascade.md b/docs/classification-cascade.md index 9b99ac2..09777b8 100644 --- a/docs/classification-cascade.md +++ b/docs/classification-cascade.md @@ -47,6 +47,14 @@ signatures, or one candidate pair. Astro, Vue and Svelte files are parsed as their scripts: Astro frontmatter and `