Mutation Testing za Solidity sa Slither (slither-mutate)
Reading time: 5 minutes
tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Mutation testing "tests your tests" tako što sistematski uvodi male promene (mutante) u vaš Solidity kod i ponovo pokreće vaš skup testova. Ako test padne, mutant se smatra ubijenim. Ako testovi i dalje prolaze, mutant preživi, otkrivajući slepu tačku u vašem skupu testova koju linijsko/gransko pokriće ne može detektovati.
Ključna ideja: pokriće pokazuje da je kod izvršen; mutation testing pokazuje da li je ponašanje zaista provereno.
Zašto pokriće može zavarati
Razmotrite ovu jednostavnu proveru praga:
function verifyMinimumDeposit(uint256 deposit) public returns (bool) {
if (deposit >= 1 ether) {
return true;
} else {
return false;
}
}
Jedinični testovi koji proveravaju samo vrednost ispod i vrednost iznad praga mogu dostići 100% line/branch coverage, a da ne asertuju granicu jednakosti (==). Refaktor u deposit >= 2 ether bi i dalje prošao takve testove, tiho kvareći logiku protokola.
Mutation testing otkriva ovaj prazninu mutiranjem uslova i proverom da li vaši testovi zakažu.
Common Solidity mutation operators
Slither’s mutation engine primenjuje mnogo malih izmena koje menjaju semantiku, kao što su:
- Zamena operatora:
+↔-,*↔/, itd. - Zamena dodele:
+=→=,-=→= - Zamena konstanti: non-zero →
0,true↔false - Negacija/izmena uslova unutar
if/petlji - Zakomentarisati cele linije (CR: Comment Replacement)
- Zameniti liniju sa
revert() - Zamene tipova podataka: npr.
int128→int64
Cilj: Ugasiti 100% generisanih mutanata, ili opravdati preživele jasnim obrazloženjem.
Running mutation testing with slither-mutate
Zahtevi: Slither v0.10.2+.
- List options and mutators:
slither-mutate --help
slither-mutate --list-mutators
- Foundry example (uhvati rezultate i sačuvaj kompletan log):
slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results)
- Ako ne koristite Foundry, zamenite
--test-cmdnačinom na koji pokrećete testove (npr.npx hardhat test,npm test).
Artefakti i izveštaji se podrazumevano čuvaju u ./mutation_campaign. Neotkriveni (preživeli) mutanti se kopiraju tamo radi inspekcije.
Understanding the output
Redovi izveštaja izgledaju ovako:
INFO:Slither-Mutate:Mutating contract ContractName
INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT
- Oznaka u uglastim zagradama je alias mutatora (npr.
CR= Comment Replacement). UNCAUGHTznači da su testovi prošli pod mutiranim ponašanjem → nedostaje asercija.
Reducing runtime: prioritize impactful mutants
Mutation kampanje mogu trajati satima ili danima. Saveti za smanjenje troškova:
- Scope: Počnite sa kritičnim contracts/directories samo, pa proširite.
- Prioritize mutators: Ako mutant visokog prioriteta na liniji preživi (npr. cela linija zakomentarisana), možete preskočiti varijante nižeg prioriteta za tu liniju.
- Paralelizujte testove ako vaš runner to dozvoljava; cache-ujte dependencies/builds.
- Fail-fast: zaustavite rano kada promena jasno demonstrira prazninu u asercijama.
Triage workflow for surviving mutants
- Inspect the mutated line and behavior.
- Reproducirajte lokalno primenom mutirane linije i pokretanjem fokusiranog testa.
- Strengthen tests to assert state, not only return values.
- Dodajte provere granica jednakosti (npr. test threshold
==). - Asertujte post-uslove: balances, total supply, efekte autorizacije i emitovane događaje.
- Replace overly permissive mocks with realistic behavior.
- Osigurajte da mocks forsiraju transfers, failure paths i event emissions koji se dešavaju on-chain.
- Add invariants for fuzz tests.
- Npr. očuvanje vrednosti, nenegativni balances, invarianti autorizacije, monotonic supply gde je primenjivo.
- Re-run slither-mutate until survivors are killed or explicitly justified.
Case study: revealing missing state assertions (Arkis protocol)
A mutation campaign during an audit of the Arkis DeFi protocol surfaced survivors like:
INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT
Komentarisanje dodele nije prekinulo testove, što ukazuje na nedostatak asercija stanja nakon izvršenja. Osnovni uzrok: kod je verovao korisnički kontrolisanom _cmd.value umesto da proveri stvarne transfere tokena. Napadač bi mogao desinhronizovati očekivane i stvarne transfere da isprazni sredstva. Rezultat: visok stepen rizika po solventnost protokola.
Smernica: tretirajte preostale mutante koji utiču na transfere vrednosti, računovodstvo ili kontrolu pristupa kao visokorizične dok se ne uklone.
Praktična kontrolna lista
- Pokrenite ciljanu kampanju:
slither-mutate ./src/contracts --test-cmd="forge test"- Razvrstajte preostale mutante i napišite testove/invarijante koji bi pali pod izmenjenim ponašanjem.
- Potvrdite bilanse, ukupnu ponudu, autorizacije i događaje.
- Dodajte granične testove (
==, overflows/underflows, zero-address, zero-amount, empty arrays). - Zamenite nerealne mock-ove; simulirajte režime otkaza.
- Iterirajte dok svi mutanti nisu uklonjeni ili opravdani komentarima i obrazloženjem.
References
- Use mutation testing to find the bugs your tests don't catch (Trail of Bits)
- Arkis DeFi Prime Brokerage Security Review (Appendix C)
- Slither (GitHub)
tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks