Teku

QuantstampRepository at commit 1069ade

Quantstamp reviewed Teku on 29 Sep 2020: 29 findings, 0 critical; 20 marked fixed, 8 acknowledged, 1 open.

No open critical findings
Open the reportOpen Teku’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings29

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High001
Medium125
Low0614
HighUnlimited Inbound Message QueueFixed

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.

Medium`beacon_aggregate_and_proof` Logic Does Not Reject Aggregates that Fail Ancestry ConditionFixed

The 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.

Medium`beacon_attestation_{subnet_id}` Logic Does Not Reject Attestations that Fail Ancestry ConditionFixed

The 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.

Medium`beacon_block` Logic Does Not Reject Blocks that Fail Ancestry ConditionFixed

The 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.

MediumMessage Encoding is ChangeableFixed

According 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.

MediumMethod `processNewData()` Does Not Check Deposit IndexFixed

The 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.

Low`beacon_aggregate_and_proof` Has Stricter Committee Size ValidationFixed

According 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.

LowClone May Return `null`Fixed

The catch block inside `clone()` returns `null`; however, returning `null` contravenes the method's implicit contract.

LowClone method does not copy entire stateFixed

The given `clone()` implementation does not set the `_server` instance variable after a new object is created (L381).

LowGeneric Exception CaughtFixed

`discovery.util.Functions`: `aesgcm_encrypt` catches `Exception`, which is too general.

Show 10 more
LowGossip Parameter `seen_ttl` Missing in Current ImplementationFixed

According 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.

LowIgnored `InterruptedException`Fixed

On 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.

LowIncompatibility Between Gradle and Java 13Fixed

When 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.

LowIncorrect Custom Equality and Hash FunctionsFixed

Several 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.”

Lowjvm-libp2p Project `README.md` Has No Build InformationFixed

The `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.

LowNoise Library is ClonedFixed

Classes: - 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.

LowNon-Final VariableFixed

`org.ethereum.beacon.discovery.pipeline.Envelope` Line 13: UUID id is not `final`.

LowPossible `NullPointerException`Fixed

`org.ethereum.beacon.discovery.message.handler.PingHandler` Line 31 calls `.get()` on `Optional<>` without checking the value presence, can result in a `NoSuchElementException`.

LowReads Without LocksFixed

`tech.pegasys.teku.storage.store.Store` methods `equals` and `hashCode` access fields of objects without locks. The locks are needed in getters.

LowWeak Passwords Allowed for Validator AccountsFixed

The 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.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (4)

  • https://github.com/Consensys/signers/signing/secp256k1/impl/src/main/java/tech/pegasys/signers/secp256k1/azure/AzureKeyVaultSigner.java at commit 1069adefa4e1c93e7a486810cbd0dba67214745b
  • https://github.com/Consensys/discovery/src/main/java/org/ethereum/beacon/discovery/message/handler/ExternalAddressSelector.java at commit 840e90bea80699790eb750839be7402fe8b598b0
  • https://github.com/libp2p/jvm-libp2p/README.md at commit 3fd9dd92659fdfa0cb5d8be4aaa051c25a34785d
  • https://github.com/Consensys/teku/gradle.properties at commit a3f6ed9aa646a43bc04d43b22cf98ed24e5dde71

Part of Teku’s security record

Teku
Audits1 audit by 1 firmLast audit Sep 2020, by Quantstamp.
Critical findingsNo open critical findingsIn 1 report.
Open Teku’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

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