ERC-7746 조합형 보안 미들웨어 훅 (Composable Security Middleware Hooks)

Last Call · 기타 · 2024-07-17 작성

스마트 컨트랙트가 함수 실행 전후에 외부 보안 레이어를 호출해 검증을 맡길 수 있는 표준 인터페이스 ILayer를 정의합니다. 보안 검사를 본체 로직과 분리해 조합하고 교체할 수 있게 합니다.

왜 필요한가

스마트 컨트랙트의 보안 검증 로직은 대개 컨트랙트 본체 안에 함께 들어갑니다. 접근 제어나 입력 검사 같은 코드가 비즈니스 로직과 한 덩어리로 묶이면 코드가 강하게 결합되어 보안 문제만 따로 떼어 점검하거나 고치기 어렵습니다. 검사 하나를 바꾸려 해도 컨트랙트 전체를 손봐야 하고, 잘 만든 검증 로직을 다른 컨트랙트에서 그대로 재사용하기도 힘듭니다. 소프트웨어 업계에서는 요청을 처리하기 전후에 공통 검사를 끼워 넣는 미들웨어(middleware) 방식이 널리 쓰이는데, 스마트 컨트랙트에는 이런 끼워 넣기를 위한 공통 인터페이스가 없었습니다. ERC-7746은 함수 실행 전후에 호출되는 표준 훅(hook) 인터페이스를 정의해 보안 검사를 독립된 레이어로 분리하고 필요에 따라 조합하거나 업그레이드할 수 있게 합니다.

심층 설명

표준의 동기: 모놀리식 검증에서 미들웨어로

지금의 스마트 컨트랙트 보안은 검증 로직을 컨트랙트 안에 한 덩어리로 넣는 방식에 의존하는 경우가 많고 이로 인해 코드가 강하게 결합되어 보안 관심사를 분리해 다루기 어렵습니다. 원문은 업계에서 널리 쓰이는 미들웨어 방식, 즉 같은 호출 서명으로 호출을 다른 호출로 감싸는 범용적이고 반복 가능한 패턴을 도입합니다. 이를 통해 전문 보안 제공자가 특정 검사를 독립적으로 개발·유지하고(독립 보안 제공자), 레이어를 조합해 컨트랙트별 보안 프로필을 만들고(조합 가능성), 보호 컨트랙트를 바꾸지 않고 레이어를 갱신하고(업그레이드 가능성), 접근 제어·입력 정제·출력 검증 등 폭넓은 검사를 수행할 수 있습니다(유연성). 나아가 보안 제공자가 범용 서비스형 보안 오라클을 만들 기반이 됩니다.

ILayer 인터페이스: beforeCall과 afterCall

ILayer를 구현하는 컨트랙트는 두 함수를 반드시 제공해야 합니다. beforeCall은 실행 전에 호출되어 레이어별 설정 데이터(configuration), 함수 셀렉터(selector), 호출을 시작한 주소(sender), 함께 보낸 ETH 양(value), 호출 데이터(data)를 받아 검증하며 검증에 실패하면 반드시 revert해야 합니다. beforeCall이 반환하는 임의의 데이터(beforeCallResult)는 실행 후 afterCall에 그대로 전달되므로, 실행 전 상태를 기록해 두었다가 실행 후와 비교하는 검증이 가능합니다. afterCall은 같은 호출 정보에 beforeCallResult를 더해 받고 역시 검증 실패 시 반드시 revert해야 합니다.

보호 컨트랙트의 통합 규칙

보호 대상 컨트랙트는 자기 로직을 실행하기 전에 사전 검증 함수를, 실행한 뒤에 사후 검증 함수를 호출하는 방식으로 레이어를 통합할 수 있습니다(MAY). 여러 레이어를 등록해 정해진 순서대로 실행할 수 있으며 어느 한 레이어라도 revert하면 보호 컨트랙트도 반드시 revert해야 합니다(MUST). 레이어 하나의 거부만으로 트랜잭션 전체가 취소되는 안전 우선 구조입니다. 참고로 명세 본문은 이 호출을 beforeCallValidation, afterCallValidation이라고 부르지만 인터페이스 코드에 선언된 함수 이름은 beforeCall, afterCall입니다.

설계 근거: 설정 데이터, 상태 유지, 엄격한 검증, 가스 비용

레이어 설정 파라미터(원문 Rationale에서는 layerConfig로 지칭)는 레이어별 맞춤 설정을 담아 하나의 레이어 구현이 요구 사항이 다른 여러 컨트랙트를 함께 서비스할 수 있게 합니다. 레이어 호출은 정적 호출(static call)이 아니므로 레이어가 자체 상태를 유지할 수 있고 호출 횟수 제한(rate limiting)이나 사용량 추적 같은 복잡한 검증 로직을 구현할 수 있습니다. 검증 실패 시 revert를 강제한 것은 잠재적으로 위험한 트랜잭션의 실행을 막는 안전장치입니다. 레이어 실행에는 가스 비용이 따르지만 원문은 보안성과 모듈성의 이점이 비용보다 크며 가스 비용은 시간이 지나며 내려갈 것으로 기대한다고 설명합니다.

참조 구현: RateLimitLayer가 자금 탈취를 막는 시험

참조 구현 저장소에는 ILayer.sol 인터페이스와 함께 Protected.sol, RateLimitLayer.sol, Drainer 컨트랙트가 있습니다. Protected 컨트랙트에는 상태에 대한 부분적 무단 접근을 허용하는 버그가 있다고 가정하고 취약한 상황을 흉내 내는 Drainer가 악의적으로 자금을 빼내려 시도합니다. RateLimitLayer는 ILayer를 구현해 클라이언트가 설정한 속도 제한을 강제하는데, 이 시험에서는 같은 발신자가 한 블록에 트랜잭션 10건까지만 보낼 수 있도록 설정되어 있습니다. test.ts의 시험은 이 조건에서 Drainer가 Protected의 자금을 빼내지 못함을 확인합니다.

진행 상태: Last Call

이 제안은 Standards Track ERC이며 원문 기준 상태가 Last Call(최종 의견 수렴)입니다. 최종 의견 수렴 마감일은 2025년 7월 29일로 명시되어 있습니다. 아직 최종 확정(Final) 단계에 이른 표준은 아니라는 점을 염두에 두어야 합니다.

쓸 때 주의할 점

ERC 원문 · ← ERCs