sherlock-2025-06-symbiotic-relay-m02

[M-02] Enabling the whitelist can grant a malicious operator a temporary whitelisted status

보고서

Summary

OperatorWhitelist.unwhitelistOperator 는 허용리스트에 등록된 오퍼레이터에 대한 호출만 허용하기 때문에 허용리스트 기능 활성화 이전에 등록했던 오퍼레이터를 해지할 수 없다.

Keyword

allowlist, logic flaw

Vulnerability

OperatorWhitelist.unwhitelistOperator 를 호출하면 허용리스트에서 오퍼레이터를 삭제하고, 이 오퍼레이터가 이미 등록된 상태라면 이를 해지한다. 하지만 허용리스트에 등록된 적이 없던 오퍼레이터라면 트랜잭션이 취소된다. 따라서 허용리스트 기능을 활성화하기 전에 등록했던, 허용리스트가 아닌 오퍼레이터는 해지할 수 없다.

function _unwhitelistOperator(
    address operator
) internal virtual {
@>  if (!isOperatorWhitelisted(operator)) {
        revert OperatorsWhitelist_OperatorNotWhitelisted();
    }
    _getOperatorsWhitelistStorage()._whitelisted[operator] = false;
    if (isWhitelistEnabled() && isOperatorRegistered(operator)) {
@>      _unregisterOperator(operator);
    }
 
    emit UnwhitelistOperator(operator);
}

다음과 같은 시나리오에서 문제가 발생한다.

  1. 허용리스트 기능을 끈다.
  2. 오퍼레이터 X가 등록을 함. 오퍼레이터 X 는 허용리스트에 등록되지 않았음.
  3. 이후 허용리스트 기능을 활성화 함
  4. OperatorWhitelist.unwhitelistOperator(operatorX) 를 호출하여 오퍼레이터 X 를 해지하고 싶지만 오퍼레이터 X는 허용리스트에 등록되어 있지 않으므로 트랜잭션이 취소된다.

Impact

허용리스트가 아닌 오퍼레이터를 해지시킬 수 없음

Mitigation

허용리스트가 아닌 오퍼레이터를 대상으로 _unwhitelistOperator 를 호출할 수 있도록 한다.

function _unwhitelistOperator(
    address operator
) internal virtual {
-   if (!isOperatorWhitelisted(operator)) {
-       revert OperatorsWhitelist_OperatorNotWhitelisted();
-   }
    _getOperatorsWhitelistStorage()._whitelisted[operator] = false;
    if (isWhitelistEnabled() && isOperatorRegistered(operator)) {
        _unregisterOperator(operator);
    }
 
    emit UnwhitelistOperator(operator);
}

tags: bughunting, symbiotic, smart contract, solidity, severity medium, allowlist, logic flaw