TL;DR: A Maven Central jar published as io.github.davidtimur:c2-lab executed a remote-access payload during compilation when placed on the annotation-processor path, while rebuilding its command channel across nine releases and even disabling TLS validation in the final version, according to Xygeni. The case shows that build-time execution boundaries in Java are broader than many supply-chain scanners assume, especially when service registration files trigger code outside source-level review.
At a glance
What this is: This is a supply-chain analysis of a malicious Maven artifact that turned javac into an execution engine during compilation.
Why it matters: It matters because build pipelines, dependency scanners, and IAM-adjacent controls around code signing, repository trust, and CI execution boundaries all need to treat compiler-triggered code as active runtime risk, not inert package content.
By the numbers:
- When AWS credentials are exposed publicly, attackers attempt access within an average of 17 minutes, and as quickly as 9 minutes in some cases.
👉 Read Xygeni's analysis of the JavacDoor Maven artifact and build-time execution
Context
JavacDoor is a build-pipeline supply-chain problem, not a normal package-install problem. The key issue is that Java annotation processors can execute during compilation, which means a jar on the annotation-processor path can behave like code execution rather than passive dependency material.
For identity and access practitioners, the interesting intersection is not user IAM but the governance of build identities, repository trust, and secret exposure in CI systems. That is where secrets, tokens, signing keys, and workload permissions can turn a malicious artifact into a broader compromise path.
The starting position is atypical only in its explicitness. Most malicious package cases hide behind ordinary dependency behaviour, while this one used a documented compiler feature as the trigger.
Key questions
Q: What breaks when a Java artifact can execute during compilation?
A: The normal assumption that dependencies are inert until imported breaks immediately. A compiler-loaded processor can run code on the build machine, touch secrets, call out to the network, and modify build trust without any application-level reference. That turns dependency approval into execution approval and makes the build pipeline part of the threat surface.
Q: Why do build systems need identity controls as well as package controls?
A: Because the real target is often the build service account, signing key, or artifact publishing credential. If those identities have broad, persistent access, a malicious dependency can pivot from compile-time execution into repository tampering or deployment compromise. Least privilege and short-lived credentials matter in CI just as they do in production.
Q: How do security teams detect malicious behaviour hidden inside jars?
A: They need structural parsing, not text grepping. That means enumerating service-provider files, unpacking class constant pools, watching for unexpected compiler subprocesses, and correlating build logs with network egress. If a jar is treated as a bag of files instead of an executable container, malicious compiler-time payloads can slip through.
Q: Who is accountable when a build dependency steals source code?
A: Accountability usually spans engineering, platform security, and supply chain governance. Engineering owns dependency selection, platform teams own build isolation and egress controls, and security owns detection and policy enforcement. For regulated environments, the question becomes whether the organisation can prove it had reasonable controls over code provenance and execution.
Technical breakdown
Annotation processors as an execution path
Java annotation processing is designed to inspect source at compile time and generate code or metadata. The compiler discovers processors through META-INF/services/javax.annotation.processing.Processor and loads the named class automatically. That means a jar on the processor path does not need to be imported by application code, referenced by annotations, or activated by an install script. If the bytecode contains a processor implementation, javac will instantiate it as part of the build. The important distinction is between dependency presence and execution boundary: the latter is much broader than many teams assume.
Practical implication: treat the annotation-processor path as an execution boundary and inventory it separately from the normal compile classpath.
Why service registration is harder to spot than lifecycle hooks
Unlike npm postinstall scripts or Python import-time payloads, a Java service registration is a plain-text file inside the jar that names a class to load. The behaviour is then buried in compiled bytecode elsewhere in the archive. Text-only scanning often misses this because the trigger is not a manifest hook in the usual sense and the payload strings may exist only inside class constant pools. This makes jar analysis a container-format problem, not just a source-code review problem.
Practical implication: parse jars structurally and enumerate service-provider files before deciding a package is safe to consume.
Build-time payloads can change transport without changing the trigger
Once compile-time execution is available, the payload can evolve independently of the original entry point. In this case the channel changed multiple times across releases, moving from a callback URL to a reverse shell and then to HTTP polling, while the compile trigger stayed constant. The final release also disabled TLS verification inside the JVM, which expands the blast radius because later HTTPS traffic in the same build process can be accepted without certificate validation. The build step itself becomes a transient but high-trust runtime.
Practical implication: monitor compiler subprocesses and outbound network behaviour during builds, not just package installation events.
Threat narrative
Attacker objective: The attacker objective was to execute commands from the build environment and establish a controllable channel from downstream compilation pipelines.
- Entry occurred when a jar on the annotation-processor path exposed a service-registration file that javac automatically loaded during compilation.
- Credential or channel control was established through callback infrastructure, reverse-shell transport, and later HTTP polling channels embedded in the payload.
- Impact came from remote command execution inside the build process, with one release also disabling TLS validation for the JVM session.
NHI Mgmt Group analysis
Compiler-triggered execution is a supply-chain risk class of its own: this case is not just malware in a jar, it is build-time code execution through a documented language feature. That makes the control problem different from simple dependency approval, because the trigger sits in compiler semantics and service discovery. Teams should therefore classify annotation processors as active execution artifacts, not passive libraries.
Service-provider discovery creates a blind spot that many scanners still miss: the malicious behaviour did not begin in source code or a manifest hook, but in META-INF/services registration inside the archive. That is a structural gap in many container and dependency inspection flows, which still over-focus on install-time scripts. The lesson is to scan the archive as an executable structure, not as text.
Build identities need the same governance discipline as production identities: a compromised build path can expose tokens, signing material, artifact publishing credentials, and downstream deployment permissions. This is where NHI governance intersects with software supply chain security, because CI runners and build service accounts are high-value non-human identities. Practitioners should treat build-time access as privileged access with a narrow, auditable lifespan.
Compile-time trust is being stretched by the package ecosystem faster than static policy can keep up: the final release’s permissive TLS changes show how a build implant can alter transport trust inside a transient JVM session. That creates governance debt for teams that rely on repository allowlists alone. The practical conclusion is to control both dependency provenance and the runtime behaviour of build tools.
Named concept: build-path execution exposure is the governance gap where a package becomes dangerous not when installed, but when it is merely present on a compiler or tool-specific execution path. This concept matters because modern software pipelines increasingly contain hidden execution surfaces inside otherwise routine developer workflows. Security teams should map those surfaces explicitly and review them as part of supply-chain risk management.
What this signals
A build pipeline that can execute code during compilation needs a different control model from ordinary dependency hygiene. The relevant risk is not only whether the package is trusted, but whether the toolchain itself creates hidden execution surfaces that can reach secrets, signing keys, or deployment credentials.
Build-path execution exposure: teams should now treat compiler-triggered loading, service discovery, and build-time egress as first-class governance signals. That means mapping non-human identities in CI to the same lifecycle controls used for privileged production access, including scope limitation, rotation, and auditable ownership.
If you already monitor secrets and artifact provenance, the next maturity step is to connect those controls to the build runtime itself. External guidance such as NIST SP 800-53 Rev 5 Security and Privacy Controls and CIS Controls v8 becomes more actionable when applied to compiler behaviour, not just repository intake.
For practitioners
- Classify annotation-processor paths as executable trust zones Inventory every dependency that can be loaded by javac, and separate those artifacts from normal compile-classpath libraries. Require explicit approval for any jar that registers META-INF/services/javax.annotation.processing.Processor.
- Inspect jar service-registration files before promotion Build a control that parses archives for service-provider entries, then traces each named class into bytecode and constant pools. Do not rely on source scanning alone, because the payload may live entirely outside readable source.
- Monitor compiler subprocesses and outbound build traffic Alert when javac spawns shell processes or when build jobs make unexpected outbound connections during compilation. Compile-time network egress should be rare enough to treat as a high-confidence signal.
- Restrict build identities to short-lived, minimal permissions Apply least privilege to CI service accounts, artifact signing keys, and repository credentials so a malicious processor cannot pivot from build execution into publishing or deployment. Rotate secrets that touch the build path on a tighter schedule than application secrets.
- Block unvalidated TLS behaviour in build tooling Disallow build steps that override JVM trust managers or hostname verification, because that can silently downgrade certificate checks for the rest of the process. Treat permissive TLS changes in build code as a policy violation.
Key takeaways
- JavacDoor shows that a jar can become an execution payload during compilation, even when no application code imports it.
- The compromise surface extends beyond package installation into service registration, compiler subprocesses, and build-time network egress.
- Teams should govern build identities, parse jars structurally, and treat annotation processors as privileged execution inputs.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK address the attack and risk surface, while NIST CSF 2.0, NIST SP 800-53 Rev 5 and CIS Controls v8 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | TA0002 , Execution; TA0011 , Command and Control | The artifact executes during compile time and establishes outbound control channels. |
| NIST CSF 2.0 | PR.AC-4 | Build-path access and least privilege are central to this supply-chain issue. |
| NIST SP 800-53 Rev 5 | IA-5 | Credential and authenticator management applies to build secrets touched by the payload. |
| CIS Controls v8 | CIS-5 , Account Management | CI and repository accounts need strict lifecycle control in this attack pattern. |
Use CIS-5 to inventory and constrain build accounts, then remove standing access from unused automation identities.
Key terms
- Annotation Processor: A Java component that runs during compilation to inspect source and optionally generate code or metadata. It is loaded by the compiler from service registration, which makes it an execution mechanism rather than a passive library feature when abused by a malicious artifact.
- Execution-Path Exposure: Execution-path exposure is the risk that a credential or sensitive action becomes dangerous because it is used inside an attacker-influenced workflow. The secret may be valid, but the path it takes can still hand control to an adversary. This is a runtime identity problem, not only a storage problem.
- Compiler Subprocess Telemetry: Logs and process events showing what a compiler spawned during a build, including shells, helper binaries, and network-connected child processes. It is one of the clearest ways to detect malicious compile-time behaviour because the payload often disappears when the build ends.
- Build identity: The set of credentials, tokens, keys, and permissions used by CI/CD systems, runners, and developer tooling. Build identity is often overlooked, yet it can expose secrets, alter repositories, and propagate compromise into downstream software if not tightly scoped and monitored.
What's in the full report
Xygeni's full article covers the operational detail this post intentionally leaves for the source:
- Release-by-release timeline showing how the payload changed from callback to reverse shell to HTTP polling
- Constant-pool indicators and build-log markers that help distinguish this artifact from ordinary annotation processors
- Observed network paths, headers, and TLS manipulation patterns for deeper incident triage
- Removal details for the artifact and group from Maven Central, useful for provenance investigations
👉 The full Xygeni post covers the artifact timeline, compiler indicators, and build-machine telemetry
Deepen your knowledge
NHI Foundation Level course, the industry's only accredited NHI security programme, covers NHI governance, machine identity security, secrets management, and identity lifecycle controls. It helps security and platform teams apply identity discipline to build pipelines, service accounts, and other non-human identities.
Published by the NHIMG editorial team on August 18, 2026.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org