As of 3 Nov 2026, Teku has 1 audit report on Trustblock, by Quantstamp, dated 29 Sep 2020. That report lists no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Teku | Security firm: Quantstamp | Date: | Scope: Repository at commit 1069ade | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 1 |
| Medium | 1 | 2 | 5 |
| Low | 0 | 6 | 14 |
According to the Eth2 p2p spec, *“for any optional queueing, clients SHOULD maintain maximum queue sizes to avoid DoS vectors”*. Currently, Teku queues inbound messages indirectly by running their processing function asynchronously; there does not seem to exist any limitation on the maximum size of the queue. Without such a control, the node is potentially subject to DoS attacks.
Open the reportThe validation logic for the `beacon_aggregate_and_proof` topic does not reject aggregates when they do not satisfy the following condition, as per Eth2 p2p spec: *“[REJECT] The current finalized_checkpoint is an ancestor of the block defined by aggregate.data.beacon_block_root – i.e. get_ancestor(store, aggregate.data.beacon_block_root, compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == store.finalized_checkpoint.root”* As such, Teku’s client will queue aggregates that other clients from other implementations would immediately reject.
Open the reportThe validation logic for the `beacon_aggregate_and_proof` topic does not reject attestations when they do not satisfy the following condition, as per Eth2 p2p spec: *“[REJECT] The current finalized_checkpoint is an ancestor of the block defined by attestation.data.beacon_block_root – i.e. get_ancestor(store, attestation.data.beacon_block_root, compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == store.finalized_checkpoint.root”* As such, Teku’s client will queue attestations that other clients from other implementations would immediately reject.
Open the reportThe validation logic for the `beacon_block` topic does not reject blocks when they DO NOT satisfy the following condition, as per Eth2 p2p spec: *“[REJECT] The current finalized_checkpoint is an ancestor of block – i.e. get_ancestor(store, block.parent_root, compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == store.finalized_checkpoint.root”* As such, Teku’s client will queue blocks that other clients from other implementations would immediately reject.
Open the reportAccording to specification implementations MUST use a single encoding. Changing an encoding will require coordination between participating implementations. While the current testnet is using a single encoding, clients are currently allowed to switch encodings for a given client from regular SSZ to Snappy, which could lead to network partitions.
Open the reportThe function `processNewData()` doesn't check the deposit index which may result in wrong synchronization and hence the client may be out of sync with the network.
Open the reportAccording to the Eth2 p2p spec, “The attestation has participants – that is, len(get_attesting_indices(state, aggregate.data, aggregate.aggregation_bits)) >= 1”. If not, the attestation should be rejected. The code, however, performs the following check: ``` final List<Integer> committee = get_beacon_committee( state, attestation.getData().getSlot(), attestation.getData().getIndex()); if (committee.size() != attestation.getAggregation_bits().getCurrentSize()) { return REJECT; } ``` This is not the same as stated in the specification; it is a stricter condition: it checks that the number of participants in the attestation is the same as the committee size (a number greater than zero). Although it seems a correct check to make, it does not find a match in the specification.
Open the reportThe catch block inside `clone()` returns `null`; however, returning `null` contravenes the method's implicit contract.
Open the reportThe given `clone()` implementation does not set the `_server` instance variable after a new object is created (L381).
Open the report`discovery.util.Functions`: `aesgcm_encrypt` catches `Exception`, which is too general.
Open the reportAccording to the Eth2 p2p spec, the gossipsub implementation should support a set of parameters, including `seen_ttl`, which controls the number of heartbeat intervals to retain message IDs. Moreover, `seen_ttl`should be set to 550. This is not yet implemented in the current libp2p code. The existing control in place is limited to a Least Replacement Policy caching, where up to 10K messages will be stored at a time.
Open the reportOn Line 400, `InterruptedException` handling is simply ignored. The throwing of `InterruptedException` clears the interrupted state of the `Thread`, so if the exception is not handled properly the fact that the thread was interrupted will be lost.
Open the reportWhen attempting to build the `libp2p/jvm-libp2p.git` repository using a Java 13 setup, Gradle reports the following error: ``` FAILURE: Build failed with an exception. * Where: Settings file '/Users/developer/Documents/Projects/audits-code/teku/jvm-libp2p/settings.gradle' * What went wrong: Could not compile settings file '/Users/developer/Documents/Projects/audits-code/teku/jvm-libp2p/settings.gradle'. > startup failed: General error during semantic analysis: Unsupported class file major version 57 java.lang.IllegalArgumentException: Unsupported class file major version 57 at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:184) at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:166) at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:152) at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:273) at org.codehaus.groovy.ast.decompiled.AsmDecompiler.parseClass(AsmDecompiler.java:81) at org.codehaus.groovy.control.ClassNodeResolver.findDecompiled(ClassNodeResolver.java:254) at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:192) at org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:172) at org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:128) [...] ``` The error above stems from the fact the Gradle version in use (5.1.4) does not support Java 13 - see [issue 10785 in their Github repository](https://github.com/gradle/gradle/issues/10785). Support for Java 13 is planned for Gradle 6+. If the build is broken or with missing supporting documentation, external contributors and users seeking to validate and/or experiment with unstable releases may be discouraged to do so.
Open the reportSeveral classes have issues with overriding their `equals` and/or `hashCode` functions. - `org.ethereum.beacon.discovery.message.NodesMessage`: `equals` and `hashCode` do not take in the collection of nodes, just its size. - `DiscoveryV5Message`: the `equals` and `hashCode` methods are not overriden. - `src/main/java/io/libp2p/discovery/mdns/impl/DNSRecord.java`: `equals` is overriden, but `hashCode` is not. According to the Java Language Specification, there is a contract between `equals(Object)` and `hashCode()`: “If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables. In order to comply with this contract, those methods should be either both inherited, or both overridden.”
Open the reportThe `README.md` file does not provide instructions on how to build the project. When lacking documentation, external contributors and users seeking to validate and/or experiment with unstable releases may be discouraged to do so.
Open the reportClasses: - com.southernstorm.noise.crypto.* - com.southernstorm.noise.protocol.* The Noise library dependency is not managed by Gradle. Instead, its code has been cloned from ([https://github.com/rweather/noise-java](https://github.com/rweather/noise-java)), without any reference to what commit head was used. As a negative side-effect, any updates or vulnerability fixes in the upstream repository must be manually tracked, pulled, and merged by Teku developers, which if not done regularly, could lead to bugs or security issues being left unfixed.
Open the report`org.ethereum.beacon.discovery.pipeline.Envelope` Line 13: UUID id is not `final`.
Open the report`org.ethereum.beacon.discovery.message.handler.PingHandler` Line 31 calls `.get()` on `Optional<>` without checking the value presence, can result in a `NoSuchElementException`.
Open the report`tech.pegasys.teku.storage.store.Store` methods `equals` and `hashCode` access fields of objects without locks. The locks are needed in getters.
Open the reportThe node allows weak passwords for validator accounts. Validators might have their passwords brute-forced in a relatively small time frame if poor passwords are chosen.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="teku"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us