우리는 Solidity를 통해 개발 된 스마트 계약이 알려 지거나 알려지지 않은 다양한 공격에 취약한 것처럼 작은 허점이 어떻게 재정적 손실 (다양한 규모)로 이어지는 지 살펴 보았습니다. 악용자는 버그와 허점을 이용하여 스마트 계약을 들여다보고이를 조작하여 공격을 수행합니다. 여기에서는 Solidity 프로그래밍 언어에서 일반적으로 발생하는 상위 5 개의 오류에 대한 포괄적 인 목록을 제공합니다.
QuillAudits에서는 모든 해킹의 요지를 파악하고 잠재적 인 위협을 피하기 위해 미래의 스마트 계약에 대한 학습을 구현하는 적응 형 방법론을 따릅니다.
견고성 프로그래밍 언어의 오류
1. 확인되지 않은 외부 통화
이 문제는 가장 일반적으로 관찰되는 Solidity 함정 중 하나이기 때문에 처음부터이 문제를 당깁니다. 일반적으로 이더를 외부 계정으로 보내는 것은 다음을 통해 수행됩니다. 이전() 함수. 이 외에도 외부 호출에 가장 널리 사용되는 두 가지 함수는 다음과 같습니다. 요구()및 보내다(), 여기에서 주로 요구() 함수는 개발자의 다양한 외부 호출을 수행하는 데 광범위하게 사용됩니다.
비록 요구() 와 보내다() 함수는 호출이 성공했는지 여부를 지정하는 부울 값을 반환합니다. 따라서이 경우 기능 중 하나가 요구() or 보내다() 작업을 수행하지 못하면 그릇된. 따라서 개발자가 반환 값을 교차 확인하지 않으면 함정이됩니다.
취약점
아래 예를 고려하십시오.
로또 계약 {
boolpublic payedOut = false;
공개 우승자에게 연설;
uintpublic winAmount;
//… 여기에 추가 기능
function sendToWinner () public {
require (! payedOut);
winner.send (winAmount);
payedOut = true;
}
function withdrawLeftOver () public {
require (payedOut);
msg.sender.send (this.balance);
}
}
위의 로또와 같은 계약에서 우리는 수상자 수신 승금액 이더의 약간의 잔여 물은 외부 에이전트로부터 제거됩니다.
여기서 계약의 함정은 [11] 행에 있습니다. 보내다 응답의 교차 검증없이 사용됩니다. 위의 예에서 수상자 거래가 실패한 경우 (Gas 부족 또는 의도적으로 대체 기능을 던지는 계약 인 경우), 권한 부여 지불 설정 될 참된 에테르 거래의 성공 여부와 관계없이. 이 경우 모든 악용자는 승자의 상금을 통해 철수 기능.
QuillAudit의 접근 방식
우리의 사내 개발자 팀은 다음을 사용하여이 버그를 해결합니다. [이전] 대신 기능 [보내다] 기능, 외부 트랜잭션이 되 돌리면 [transfer]가 되돌립니다. [send]를 사용하는 경우 항상 반환 값을 교차 확인하십시오.
우리가 따르는 강력한 접근 방식 중 하나는 [금단 패턴]을 활용하는 것입니다. 여기서 우리는 논리적으로 외부 전송 기능을 나머지 코드베이스와 분리하고, 최종 사용자가 인출 기능을 호출하는 사람이므로 잠재적으로 실패한 트랜잭션의 부담을 최종 사용자에게 부여합니다.
2. 재입국
이더 리움 스마트 계약은 다른 외부 계약의 코드를 호출하고 활용하며이를 수행하기 위해 계약은 외부 호출을 제출해야합니다. 이러한 외부 호출은 취약하고 공격에 취약하며 최근 DAO 해킹의 경우 이러한 공격이 발생했습니다.
취약점
공격자는 계약이 알 수없는 주소로 에테르를 보낼 때 이러한 공격을 수행합니다. 이 경우 공격자는 폴백 기능에서 악성 코드를 소유 한 외부 주소에서 컨트랙트를 생성 할 수 있으며 컨트랙트가이 주소로 이더를 보낼 때이 악성 코드가 호출됩니다.
것: '재진입'이라는 용어는 외부 악성 계약이 취약한 계약에 대해 함수를 호출 한 후 코드 실행 경로가이를 '재진입'한다는 사실에서 유래되었습니다.
아래의 예를 살펴보면 예금자가 주당 1 개의 이더 만 인출 할 수있는 이더 리움 금고입니다.
계약 EtherStore {
uint256 public withdrawalLimit = 1 에테르;
mapping (address => uint256) public lastWithdrawTime;
mapping (address => uint256) public balances;
function depositFunds () external payable {
잔액 [msg.sender] + = msg.value;
}
함수 철회 자금(uint256 _weiToWithdraw) 공개 {
require (잔액 [msg.sender]> = _weiToWithdraw);
// 출금 제한
require (_weiToWithdraw <= withdrawalLimit);
// 출금 허용 시간 제한
require (현재> = lastWithdrawTime [msg.sender] + 1 주);
require (msg.sender.call.value (_weiToWithdraw) ());
잔액 [msg.sender]-= _weiToWithdraw;
lastWithdrawTime [msg.sender] = 지금;
}
}
위 계약에서 우리는 [depositFunds]와 [withdrawFunds]의 두 가지 공용 기능을 가지고 있습니다. [depositFunds]는 송금인의 잔액을 늘리는 데 사용되는 반면 [withdrawFunds]는 인출 할 금액을 지정합니다. 이 경우 인출 할 금액이 1 에테르 미만이면 성공합니다.
여기서 함정은 에테르의 이동이 일어나는 라인 [17]에 있습니다. 공격자는 [EtherStores]의 계약 주소를 유일한 생성자 매개 변수로 사용하여 악성 계약을 생성 할 수 있습니다. 이것은 [etherStore]를 공용 변수로 만들어 공격을 받기 쉽습니다.
QuilllAudit의 접근 방식
우리는 스마트 계약에서 잠재적 인 재진입 취약점을 피하기 위해 다양한 기술을 따릅니다. 가장 먼저 가능한 가장 좋은 방법은 이더를 외부 계약으로 전송할 때 내장 된 [전송] 기능을 사용하는 것입니다.
둘째, 컨트랙트에서 이더를 보내기 전에 상태 변수의 모든 논리 변경이 완료되도록하는 것이 중요합니다. [EtherStore] 예제에서 라인 [18]과 [19]는 라인 [17] 앞에 있어야합니다.
세 번째 기술을 사용하여 재진입 호출을 방지 할 수도 있습니다. 뮤텍스의 도입을 통해. 코드 실행 중에 계약을 잠그는 상태 변수의 추가입니다.
3. 기본 가시성
Solidity에서 사용하는 함수에 대한 가시성 지정자가 있으며 호출 할 수있는 방법을 규정합니다. 함수 호출을 결정하는 것은 가시성입니다. 사용자가 외부 적으로, 다른 파생 계약에 의해 내부적으로 만 또는 외부 적으로 만. 가시성 지정자를 잘못 사용하면 스마트 계약에서 얼마나 큰 취약성을 유발할 수 있는지 살펴 보겠습니다.
취약점
기본적으로 함수의 가시성은 [공용]이므로 외부 사용자가 특정 가시성없이 함수를 호출 할 수 있습니다. 이 버그는 개발자가 비공개 (또는 계약 자체 내에서 호출 할 수있는) 기능에 대한 가시성을 지정하는 것을 잊었을 때 발생합니다. 예를 들면 다음과 같습니다.
계약 HashForEther {
function withdrawWinnings () {
// 주소의 마지막 8 자리 0 진수가 XNUMX이면 우승자
require (uint32 (msg.sender) == 0);
_sendWinnings ();
}
function _sendWinnings () {
msg.sender.transfer (this.balance);
}
}
위 계약은 간단한 주소 추측 바운티 게임입니다. 여기에서 함수의 가시성이 지정되지 않았 음을 알 수 있습니다. 특히 [_sendWinnings] 함수는 [public] (기본값)이므로 모든 주소를 통해 호출하여 현상금을 훔칠 수 있습니다.
QuillAudit의 접근 방식
우리의 사내 팀은 항상 최상의 감사 관행을 따르는 노련한 개발자들로 구성되어 있습니다. 여기서 기능의 가시성은 공개적으로 유지 되더라도 명시 적으로 지정해야합니다.
4. 생성자 사용 보호
일반적으로 생성자는 계약을 초기화하는 동안 중요하고 권한있는 작업을 수행하는 데 사용되는 특수 기능이라고합니다. Solidity [v0.4.22] 이전에는 생성자가이를 포함하는 계약에서 사용한 것과 동일한 이름을 사용했습니다. 이제 개발 단계에서 계약 이름이 변경되었지만 생성자 이름은 동일하게 유지되는 경우를 생각해보십시오.이 허점은 공격자에게 스마트 계약에 대한 쉬운 진입을 제공 할 수도 있습니다.
취약점
계약 이름은 수정되었지만 생성자의 이름은 변경되지 않은 경우 심각한 결과를 초래할 수 있습니다. 예를 들면 :
계약 OwnerWallet {
공공 소유자에게 주소를 지정하십시오.
// 생성자
function ownerWallet (address _owner) public {
소유자 = _owner;
}
// 대체. 에테르를 모으십시오.
함수 () 지급 {}
function withdraw () public {
require (msg.sender == 소유자);
msg.sender.transfer (this.balance);
}
}
위의 계약에서 [withdraw] 함수를 호출하여 소유자 만 이더를 인출 할 수 있음을 알 수 있습니다. 여기에서 생성자의 이름이 계약서와 다르기 때문에 취약점이 발생합니다 (첫 글자가 다릅니다!). 따라서 익스플로잇은 [ownerWallet] 함수를 호출하여 자신을 소유자로 인증 한 다음 [withdraw]를 호출하여 계약에있는 모든 이더를 인출 할 수 있습니다.
QuillAudit의 접근 방식
우리는 Solidity 컴파일러의 버전 [0.4.22]를 준수합니다. 이 버전은 키워드를 도입했습니다. 계약 이름과 일치하는 함수 이름이 필요한 [생성자].
5. Tx.Origin 인증
여기서 [Tx.Origin]은 Solidity의 전역 변수로, 원래 호출 또는 트랜잭션을 실행 한 계정의 주소를 포함합니다. 이 변수는 인증에 사용할 수 없습니다. 그렇게하면 계약이 피싱 공격에 취약 해집니다.
취약점
[tx.origin] 변수를 통해 사용자에게 권한을 부여하는 계약은 외부 공격에 노출되어 사용자가 잘못된 계약에 대해 인증 된 작업을 수행하도록합니다. 아래 예를 고려하십시오.
계약 Phishable {
공공 소유자에게 주소를 지정하십시오.
생성자(주소 _소유자) {
소유자 = _owner;
}
function () external payable {} // 이더 수집
function withdrawAll (address _recipient) public {
require (tx.origin == 소유자);
_recipient.transfer (this.balance);
}
}
여기 [11] 행에서 계약은 [tx.origin]의 도움으로 [withdrawAll] 기능을 승인합니다.
QuillAudit의 접근 방식
우리는 일반적으로 스마트 계약에서 승인을 위해 [tx.origin]을 사용하지 않습니다. [tx.origin]의 사용이 엄격히 금지되는 것은 아니지만 몇 가지 특정 사용 사례가 있습니다. [tx.origin]을 사용하여 현재 계약을 호출하는 외부 계약을 거부 할 수 있습니다. [require (tx.origin == msg.sender)] 형식의 [require]로 실행할 수 있습니다. 계약을 일반 코드없는 주소로 제한하는 현재 계약을 호출하기 위해 중간 계약을 호출하는 것을 방지하기 위해 수행됩니다.
최종 마무리
우리는 Solidity 언어의 XNUMX 가지 일반적인 함정을 포괄적으로 다루었습니다. 스마트 계약을 개발하는 동안 설계 상 변경 불가능하다는 사실을 잊지 말아야합니다. 즉, 일단 생성하면 소스 코드를 패치 할 방법이 없습니다.
이는 개발자에게 배포 전에 사용 가능한 보안 테스트 및 감사 도구를 활용하는 데 큰 도전이됩니다.
스마트 계약에 대한 잠재적 인 악의적 인 위협과 위에서 언급 한 위험 중 일부는 사내 감사 전문가 팀이 매우 독특하고 강력한 방식으로 수행합니다. QuillAudits는 계약을 안전하고 안전하게 유지하기 위해 모든 소프트웨어 보안 관행으로 계약을 업데이트하기 위해 보안 연구에 최선을 다하고 있습니다.
QuillHash에 연락
오랜 세월 동안 업계의 존재로, 퀼해시 전 세계에 엔터프라이즈 솔루션을 제공했습니다. 전문가 팀이있는 QuillHash는 DeFi 기업을 포함한 다양한 산업 솔루션을 제공하는 선도적 인 블록 체인 개발 회사입니다. 스마트 계약 감사에 도움이 필요하면 언제든지 전문가에게 문의하십시오. 여기에!
더 많은 업데이트를 위해 QuillHash를 팔로우하세요
출처 : https://blog.quillhash.com/2021/06/04/top-5-common-errors-in-solidity-programming-language/
- 11
- 계정
- 이점
- All
- 회계 감사
- 인증
- 권한 부여
- BEST
- blockchain
- 곤충
- 버그
- 전화
- 가지 경우
- 원인
- 도전
- 암호
- 공통의
- 회사
- 계약
- 계약
- Current
- DAO
- DeFi
- 디자인
- 개발자
- 개발자
- 개발
- Enterprise
- 에테르
- 이더리움
- 이벤트
- 전문가
- 페이스북
- 금융
- 먼저,
- 따라
- 형태
- 무료
- 기능
- 미래
- 경기
- 가스
- 글로벌
- 큰
- 마구 자르기
- 여기에서 지금 확인해 보세요.
- 방법
- HTTPS
- 거대한
- 포함
- 산업
- IT
- 언어
- 리드
- 지도
- 라인
- 링크드인
- 명부
- 경기
- 기타
- 소유자
- 패치
- 무늬
- 피싱
- 피싱 공격
- 처방하다
- 제시
- 사설
- 프로그램 작성
- 공개
- 당기
- 연구
- 응답
- REST
- 가장 안전한 따뜻함
- 보안
- 서비스
- 세트
- 단순, 간단, 편리
- 작은
- 스마트 한
- 똑똑한 계약
- 스마트 계약
- So
- 소프트웨어
- solidity
- 솔루션
- 주 정부
- 성공
- 지원
- 소스
- 위협
- 시간
- 상단
- 맨 5
- 거래
- 거래 내역
- us
- 사용자
- 가치
- 둥근 천장
- 가시성
- 취약점
- 취약점
- 취약
- 주
- 누구
- 이내
- 년