Assessment reports>Brevis>Informational findings>Ethereum header length checks for dynamic fields not checking ,Extra
Category: Coding Mistakes

Ethereum header length checks for dynamic fields not checking Extra

Informational Severity
Informational Impact
N/A Likelihood

Note regarding the deprecated target

Below we describe an issue in the zk-bridge repository that was part of the originally contracted scope at the start of the audit. This repository was later deprecated and removed from the scope of the audit after we had found and reported the issue described below. We keep this finding here so that the report accurately reflects the findings we identified and reported during the auditing process. Due to the deprecation of the relevant code, no action is necessary in relation to this finding.

Description

This finding concerns the function checkDynamicFieldLen that is duplicated in

  • circuits/fabric/headers/headerutil/utils.go in zk-bridge

  • circuits/fabric/smt/utils.go in zk-bridge

This function is used to check that the dynamic length fields of a Ethereum block header have reasonable sizes. It is implemented as follows:

func checkDynamicFieldLen(h types.Header) bool {
	hasErr := 0
	hasErr += checkLen("Difficulty", len(h.Difficulty.Bytes()), 7)
	hasErr += checkLen("Number", len(h.Number.Bytes()), 8)
	hasErr += checkLen("GasLimit", getUintByteLen(h.GasLimit), 4)
	hasErr += checkLen("GasUsed", getUintByteLen(h.GasUsed), 4)
	hasErr += checkLen("Time", getUintByteLen(h.Time), 4)
	hasErr += checkLen("BaseFee", len(h.BaseFee.Bytes()), 7)
	return hasErr == 0
}

While it does check the other dynamic length fields, it is missing a check for Extra. This is a field of type []byte, but it is specified by the Ethereum yellow paper that this field must be at most 32 bytes long. The function should thus also check that this is satisfied.

Impact

Headers with improperly long Extra fields may still make checkDynamicFieldLen return true, signifying proper dynamic field lengths. We are not aware of any caller for which the Extra field could be too long, however.

Recommendations

The checkDynamicFieldLen functions should also ensure that Extra is at most 32 bytes long:

func checkDynamicFieldLen(h types.Header) bool {
	hasErr := 0
	hasErr += checkLen("Difficulty", len(h.Difficulty.Bytes()), 7)
	hasErr += checkLen("Number", len(h.Number.Bytes()), 8)
	hasErr += checkLen("GasLimit", getUintByteLen(h.GasLimit), 4)
	hasErr += checkLen("GasUsed", getUintByteLen(h.GasUsed), 4)
	hasErr += checkLen("Time", getUintByteLen(h.Time), 4)
	hasErr += checkLen("BaseFee", len(h.BaseFee.Bytes()), 7)
+    hasErr += checkLen("Extra", len(h.Extra), 32)
	return hasErr == 0
}

Remediation

The code related to the finding was deprecated before completion of the audit.

Zellic © 2025Back to top ↑