Skip to content

[P2] Free inference exploit #554

Closed @akup opened 2026-01-14 12:30 UTC 4 comments Updated 2026-04-04 00:30 UTC
Priority: Low

Inference Request Processing: Security Architecture and Fix

Overview

This document explains the 2-phase inference request processing system and the security enhancement that prevents unauthorized free inference execution.

Provided exploit with a developer library that can send free inferences is provided here

Two-Phase Request Processing

Phase 1: Transfer Agent (TA) Processing

The Transfer Agent is responsible for the initial validation and routing of inference requests:

  1. Balance Verification: The TA checks the requester's balance on-chain to ensure sufficient funds for the inference request.

  2. On-Chain Transaction: The TA submits a MsgStartInference transaction to the blockchain, which:

  3. Records the inference request
  4. Escrows the required funds
  5. Assigns an executor for the request

  6. Request Forwarding: The TA forwards the modified request to the assigned executor, adding:

  7. TA address (TransferAddress)
  8. Prompt hash (PromptHash)
  9. Transfer signature (TransferSignature)
  10. Seed and InferenceId

Phase 2: Executor Agent (EA) Processing

The Executor Agent processes the inference request and executes it:

  1. Request Reception: The executor receives a request that includes:
  2. Seed and InferenceId (added by TA)
  3. TA signature and address
  4. Original request payload

  5. Trust Model: The executor trusts requests from TAs and does not re-check the requester's balance, assuming the TA has already performed this validation.

  6. Execution: The executor:

  7. Validates the TA signature
  8. Executes the inference request
  9. Submits MsgFinishInference to complete the transaction

Security Vulnerability

The Problem

The original implementation had a critical security flaw:

  • Executor Trust: The executor trusted any request that appeared to come from a TA (containing seed, InferenceId, and signature).

  • No TA Verification: The executor did not verify that the TA address (TransferAddress) belonged to an active epoch participant.

  • Exploitation Vector: An attacker could:

  • Masquerade as a TA by crafting requests with a valid signature
  • Send requests directly to executors, bypassing balance checks
  • Execute inferences for free without proper on-chain validation

Impact

This vulnerability allowed unauthorized users to:

  • Execute inference requests without proper balance verification
  • Bypass the escrow mechanism
  • Potentially abuse the system for free inference execution

Security Fix

Solution: Active Participant Verification

The fix adds a verification step in the executor's request validation to ensure that the TA is an active epoch participant.

Implementation

The fix is implemented in the getAllowedPubKeysForExecutorRequests function, which is called during executor request validation:

func (s *Server) getAllowedPubKeysForExecutorRequests(ctx echo.Context, granterAddress string) ([]string, error) {
    if !s.isAddressActiveParticipantInCurrentEpoch(granterAddress) {
        return nil, fmt.Errorf("granter is not active in the current epoch")
    }
    // ... rest of the function
}

Active Participant Check

The isAddressActiveParticipantInCurrentEpoch function performs a two-level verification:

  1. Cache Check: First checks a cached epoch group data to quickly filter out non-participants.

  2. On-Chain Verification: Queries the current epoch group data to verify:

  3. The address is in the ValidationWeights list
  4. The participant has a non-zero weight (hasn't been marked as invalid)

This ensures that only validators who are:

  • Active in the current epoch = participating in Proof of Compute (PoC) calculations
  • Not marked as invalid (due to missed confirmations or inferences)

can act as Transfer Agents.

Economic Incentive Model (proposal)

The fix leverages the existing economic incentive structure:

  • Risk of Ban: Active epoch participants risk being banned if they don't properly validate requests.

  • Reward Loss: Participants who fail to check requester balances can lose all rewards for the epoch.

  • Accountability: By restricting TA functionality to active participants, the system ensures that only entities with "skin in the game" can route inference requests.

Benefits

  1. Prevents Free Inference Abuse: Only active epoch participants can act as TAs, preventing unauthorized free inference execution.

  2. Maintains Trust Model: The executor can still trust TA requests without re-checking balance, as TAs are now verified to be accountable participants.

  3. Economic Security: The fix leverages existing economic incentives rather than adding complex technical checks.

  4. Performance: The two-level check (cache + on-chain) balances security with performance.

Code Location

  • Verification Function: isAddressActiveParticipantInCurrentEpoch() (line 593)
  • Integration Point: getAllowedPubKeysForExecutorRequests() (line 621)
  • Validation Flow: validateFullRequest() (line 645)
  • Epoch Group Data Cache: internal.NewEpochGroupDataCache() - Provides cached epoch participant data
  • Current Epoch Group Data Query: QueryCurrentEpochGroupData() - On-chain verification of active participants
  • Validation Weights: Used to determine if a participant is active and has non-zero weight

💬 Comments (4)

@tcharchian commented 2026-02-07 00:24 UTC

potentially blocked by https://github.com/gonka-ai/gonka/pull/542, investigation is needed

@gmorgachev commented 2026-03-12 16:46 UTC

postponing to 0.2.12+

@tcharchian commented 2026-04-03 22:21 UTC

@akup, probably, this issue could be canceled?

@akup commented 2026-04-04 00:30 UTC

All inferences requests attacks are legacy and should be focused on devshards


🔄 Auto-synced from Issue #554 every hour.