3 ms·
I think the difference is that annotation processors run arbitrary code at compile time. An org might have e.g. a CI with a build environment that’s not as wel
by derefr 2y ago
I think the difference is that annotation processors run arbitrary code at compile time.
An org might have e.g. a CI with a build environment that’s not as well-sandboxed as the test environment for the built app, because a Java compiler isn’t generally expected to (and other than through annotations, usually doesn’t) expose arbitrary code execution abilities to the payload of code being compiled.
- hedora 2y agoIs it actually common practice these days to have Java repositories that do not contain the build scripts, packaging, etc? The last time I looked at maven, it seemed easy enough to have it run arbitrary code directly during the build.
- kaba0 2y agoThis is mostly about supply chain attacks, where transitive dependencies are at play. Those are mostly just already built jar files, that can still contain annotation processors, but not build scripts.
- derefr 2y ago> Is it actually common practice these days to have Java repositories that do not contain the build scripts, packaging, etc? It's not that they don't contain these things; but rather that you can (and people often do) set things up so that the build scripts + packaging can be "more trusted" than the source files. If you've ever tried to set up CI on e.g. Github for an open-source project, then you might be familiar with the concept of a "PR attack" — where an external contributor forks your project, submits a PR that adds malicious code to your build scripts (to e.g. exfiltrate your build-time secrets); and then your CI "helpfully" runs those build scripts (in order to e.g. evaluate that the PR compiles + passes tests + lints in order to determine whether it should be blocked from merging or not.) GitHub and others have come up with ways around "PR attacks", that involve treating triggered automation workflows for external PRs differently: in these workflow runs, the core of the workflow — the workflow manifest file — is sourced not from the contributor's branch, but rather from the base branch that the PR aims to merge to. Now, it's up to you, as a repo maintainer, to come up with a way to bootstrap that little bit of safety (protected workflow manifest) into whole-repo "PR attack" arbitrary-code-execution protection. But usually doing so involves: 1. moving as much of the logic for executing your build as possible out of the repo itself and into buildpacks / "action" repos; and 2. sourcing any scripts you do need for the build, not from the worktree of the external PR, but rather by having the workflow environment also check out the base branch, and then running those scripts against your worktree. (IIRC the most common pattern for this is that you check out the base branch worktree, blow away its src/ dir, symbolic-link the PR branch's worktree's src/ into the base branch as src/, and then run your build in the context of the base branch.) This approach is incomplete, however, if the PR's source files can themselves be the source of arbitrary code execution.
- skissane 2y ago> An org might have e.g. a CI with a build environment that’s not as well-sandboxed as the test environment for the built app, because a Java compiler isn’t generally expected to (and other than through annotations, usually doesn’t) expose arbitrary code execution abilities to the payload of code being compiled. Is that kind of setup common though? I’ve never seen anybody running sandboxed tests but non-sandboxed compiles. In my personal experience, either one has ability to sandbox and one sandboxes everything, or one lacks that ability and sandboxes nothing I have seen compile and unit tests run directly on a Jenkins agent (with a lot of ability for the job to mangle the agent config), but then spinning up a Docker container for integration tests - but in that case the motivation for the Docker container isn’t sandboxing, and the Docker container is often given lots of privileges (like access to the Docker socket)