Overview
This issue tracks several related security and resilience improvements identified during a comprehensive codebase review. These issues share a common theme: insufficient input validation and resource limits that could lead to DOS attacks or resource exhaustion in production.
Issues
1. Missing Proof Size Validation (DOS Vector)
Severity: MEDIUM
Location: internal/orchestrator/statefetcher.go:386-394
Problem: Proof validation checks node count (max 128) but doesn't validate individual node sizes:
if len(accountProof) > maxProofNodes {
return fmt.Errorf("account proof too large: %d nodes (max %d)", ...)
}
Risk: Attacker could send 128 proof nodes, each kilobytes large, causing memory exhaustion.
Fix: Add per-node size limit (max 1KB per node for Ethereum tries):
const maxProofNodeSize = 1024 // bytes
for i, node := range accountProof {
if len(node) > maxProofNodeSize {
return fmt.Errorf("proof node %d too large: %d bytes (max %d)", i, len(node), maxProofNodeSize)
}
}
2. No Block Size Limits
Severity: MEDIUM
Location: internal/shard/chain.go:290-380
Problem: ProduceBlock() doesn't limit transaction count or cumulative block size.
Risk: Pathological transactions could produce gigantic blocks that:
- Exhaust memory during serialization
- Cause network congestion during broadcast
- Slow down block processing on receivers
Fix: Add constants and enforcement:
const (
MaxTransactionsPerBlock = 1000
MaxBlockSize = 10 * 1024 * 1024 // 10MB
)
func (c *Chain) ProduceBlock(evmState *EVMState) (*protocol.StateShardBlock, error) {
// Early exit if too many transactions
if len(c.currentTxs) > MaxTransactionsPerBlock {
c.currentTxs = c.currentTxs[:MaxTransactionsPerBlock]
log.Printf("Block capped at %d transactions", MaxTransactionsPerBlock)
}
// ... rest of function
}
3. Insufficient Validation of HTTP Responses
Severity: MEDIUM
Location: internal/orchestrator/statefetcher.go:163-169
Problem: After deserializing fetch response, no validation of:
- Balance (could be negative or impossibly large)
- Code size (could exceed block gas limit)
- CodeHash correctness (should match keccak256 of Code)
Current Code:
var fetchResp FetchStateResponse
if err := json.Unmarshal(body, &fetchResp); err != nil {
return nil, fmt.Errorf("unmarshal fetch response: %w", err)
}
if !fetchResp.Success {
return &fetchResp, fmt.Errorf("fetch failed: %s", fetchResp.Error)
}
// No validation of Balance, Code, CodeHash
Fix: Add validation after unmarshal:
if fetchResp.Balance.Sign() < 0 {
return nil, fmt.Errorf("invalid negative balance")
}
if len(fetchResp.Code) > 24576 { // EIP-170 max contract size
return nil, fmt.Errorf("code size %d exceeds limit", len(fetchResp.Code))
}
if len(fetchResp.Code) > 0 {
expectedHash := crypto.Keccak256Hash(fetchResp.Code)
if fetchResp.CodeHash != expectedHash {
return nil, fmt.Errorf("code hash mismatch")
}
}
4. No Authentication on RPC Endpoints
Severity: MEDIUM (for production deployment)
Location: All HTTP handlers
Problem: All HTTP endpoints accept requests from any origin without authentication:
/tx/submit - can submit transactions
/evm/deploy - can deploy contracts
/faucet - can mint tokens
/state/fetch - can read state
Current Protection: Relies on Docker network isolation only.
Production Requirements:
- API key verification for write operations
- Rate limiting per IP/key
- Request signing for cross-shard communication
Suggested Approach:
func (s *Server) authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
apiKey := r.Header.Get("X-API-Key")
if !isValidAPIKey(apiKey) {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
Implementation Plan
| # |
Task |
Complexity |
Priority |
| 1 |
Add proof node size validation |
Low (30 min) |
High |
| 2 |
Add block size limits |
Low (1 hour) |
High |
| 3 |
Add HTTP response validation |
Medium (2 hours) |
Medium |
| 4 |
Add authentication middleware |
Medium (4 hours) |
Low (production) |
Acceptance Criteria
Related
Labels
P2, security, enhancement
Overview
This issue tracks several related security and resilience improvements identified during a comprehensive codebase review. These issues share a common theme: insufficient input validation and resource limits that could lead to DOS attacks or resource exhaustion in production.
Issues
1. Missing Proof Size Validation (DOS Vector)
Severity: MEDIUM
Location:
internal/orchestrator/statefetcher.go:386-394Problem: Proof validation checks node count (max 128) but doesn't validate individual node sizes:
Risk: Attacker could send 128 proof nodes, each kilobytes large, causing memory exhaustion.
Fix: Add per-node size limit (max 1KB per node for Ethereum tries):
2. No Block Size Limits
Severity: MEDIUM
Location:
internal/shard/chain.go:290-380Problem:
ProduceBlock()doesn't limit transaction count or cumulative block size.Risk: Pathological transactions could produce gigantic blocks that:
Fix: Add constants and enforcement:
3. Insufficient Validation of HTTP Responses
Severity: MEDIUM
Location:
internal/orchestrator/statefetcher.go:163-169Problem: After deserializing fetch response, no validation of:
Current Code:
Fix: Add validation after unmarshal:
4. No Authentication on RPC Endpoints
Severity: MEDIUM (for production deployment)
Location: All HTTP handlers
Problem: All HTTP endpoints accept requests from any origin without authentication:
/tx/submit- can submit transactions/evm/deploy- can deploy contracts/faucet- can mint tokens/state/fetch- can read stateCurrent Protection: Relies on Docker network isolation only.
Production Requirements:
Suggested Approach:
Implementation Plan
Acceptance Criteria
Related
docs/TODO.md- prior security workLabels
P2,security,enhancement