The first Clarity static analyser that finds bugs in your smart contracts
Main Launch: https://www.gecko.security/ (Mid July)
Gecko is an open-source Clarity static analysis tool written in Rust. It currently detects two vulnerabilities: unsafe inputs and authentication via tx-sender
. When it finds these vulnerabilities, Gecko provides visual information about the bug. It also features a web UI for easy contract testing. Developers can upload and test their own contracts or input deployed contracts for Gecko to scan. This makes it useful for both pre and post-deployment testing. Gecko helps developers find vulnerabilities and improve their code comprehension. Additionally, it reassures users that the deployed contracts they interact with are safe.
![Screenshot 2024-05-31 at 08 04 45](https://private-user-images.githubusercontent.com/22000925/335587736-7b66a7f0-8017-4e7c-93a7-4c3eadb07cb9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ2MDIwNzYsIm5iZiI6MTcyNDYwMTc3NiwicGF0aCI6Ii8yMjAwMDkyNS8zMzU1ODc3MzYtN2I2NmE3ZjAtODAxNy00ZTdjLTkzYTctNGMzZWFkYjA3Y2I5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI1VDE2MDI1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTUxNGRkYmYyNDI2MzJjZjE1NTM1OTA4YTEzMjE0YjJlOWViNmI4OTFmNjQxYzkyMGU2NDI5MjI2MDEyMGYwNWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.PUvY7kayeiN62eeq1L443BX-yqgBUck5R1zDMatVZ7s)
![Screenshot 2024-05-31 at 08 04 52](https://private-user-images.githubusercontent.com/22000925/335587757-f2a983a0-67a5-4a57-905b-42a764142673.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ2MDIwNzYsIm5iZiI6MTcyNDYwMTc3NiwicGF0aCI6Ii8yMjAwMDkyNS8zMzU1ODc3NTctZjJhOTgzYTAtNjdhNS00YTU3LTkwNWItNDJhNzY0MTQyNjczLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI1VDE2MDI1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWZiNTI1ZDZhMDIwYmVjZmY1OWQ0Njk5NGQzYWExZTlkZTMyMDVhYjczMzdmOWU4MDI0YzU3NDZjNGY5YmZmYjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.pEK4MmQSj9mP0TT6PrzqjTgv0krIl_ckrcQOHVXP7dI)
![Screenshot 2024-05-31 at 08 05 19](https://private-user-images.githubusercontent.com/22000925/335587811-de7d1ea6-1e00-4875-9f02-7efbaed65592.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ2MDIwNzYsIm5iZiI6MTcyNDYwMTc3NiwicGF0aCI6Ii8yMjAwMDkyNS8zMzU1ODc4MTEtZGU3ZDFlYTYtMWUwMC00ODc1LTlmMDItN2VmYmFlZDY1NTkyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI1VDE2MDI1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTlmMGU5ZTNiYzA2NzM1YzE1OWUwOWFhMjRjOWIxYjhiY2IwMWUxM2ZjNGZhNDI1ZTg5YTc1OWRjNGZiMjY4NTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.8kHuI75qaUN4gGYrmyTsHmuD7cn6LjMIkX8HOApRURM)
![Screenshot 2024-05-31 at 08 05 29](https://private-user-images.githubusercontent.com/22000925/335587824-9b81344e-758b-4c5c-a2d1-dd178d0d7796.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ2MDIwNzYsIm5iZiI6MTcyNDYwMTc3NiwicGF0aCI6Ii8yMjAwMDkyNS8zMzU1ODc4MjQtOWI4MTM0NGUtNzU4Yi00YzVjLWEyZDEtZGQxNzhkMGQ3Nzk2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI1VDE2MDI1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTA3ZDYyZWFhZWQ0ZmQxNzczMDA1YmViMDI0NzA5YmU4NDljMTliMTI3OGU2MjgyNzEzM2IyOWJjMDkxNDdlN2QmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.NgffmU1QK1NCR3ngkTDNOAevH9XR1MZoCu0c17koXcY)
![Screenshot 2024-05-31 at 07 45 39](https://private-user-images.githubusercontent.com/22000925/335611476-f2a17c7f-0487-430f-a6e9-338fd1cf86c4.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ2MDIwNzYsIm5iZiI6MTcyNDYwMTc3NiwicGF0aCI6Ii8yMjAwMDkyNS8zMzU2MTE0NzYtZjJhMTdjN2YtMDQ4Ny00MzBmLWE2ZTktMzM4ZmQxY2Y4NmM0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI1VDE2MDI1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWY0MTg5YWZlZTNiZTNkZTUwYzQ5NzM3YTdjYWNhMTZjYzAzOWM5MWVhOGQ5NDNmMmJlYzEyNTIwMTc5YzlhN2UmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.y5BiCvfF7oDHxS7NCsXpoJEUexwEZrEEMBG9J55jp5k)
![Screenshot 2024-05-31 at 07 45 58](https://private-user-images.githubusercontent.com/22000925/335587913-f635405e-01e6-4188-923c-610ebf5d1ace.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ2MDIwNzYsIm5iZiI6MTcyNDYwMTc3NiwicGF0aCI6Ii8yMjAwMDkyNS8zMzU1ODc5MTMtZjYzNTQwNWUtMDFlNi00MTg4LTkyM2MtNjEwZWJmNWQxYWNlLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI1VDE2MDI1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI3ZTk4MmEzN2JjZWUwMTZkYTk5NDZkZjIyNzhkZWExZTMwOWE0YjkwMDRjYWEwMDJlNTM0YzcwZWYyY2RlMGMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.41ALA1QnVw7ubZ9EDLTT-DwJKHw69WXlSzRDEigWP94)
Currently Gecko only supports checking for unsafe inputs and for vulnearbilities that occur when tx-sender
is used for authentication. These were chosen as they were the most common vulnearbilities that can be found in clarity contracts see this report. The full list of vulnerabilities that will be added can be found here.
- We parse the Clarity code into a structure that Gecko can understand, this is called an Abstract Syntax Tree (AST). It represents the hierarchical structure of the code. We use the Clarity Contract Analysis Crate, which converts Clarity code into an AST and other metadata. This is the main entrypoint for Gecko.
- We then define a struct called Gecko, which implements the
ast_visitor
crate used to traverse each node and understand the behaviour of the code. - Taint analysis is used to track the flow of potentially unsafe data through the program and locate bugs and vulnearbilities. This involves defining the vulnearbility detectors as invariants and tracking the data to ensure it is properly checked or sanitized.
- As Gecko traverses the tree it propagates this taint to other nodes that depend on these.
- Once the traversal is complete messages are displayed about issues found including the location of the bug in source.
Gecko Technical Architecture
Example of a traversal of AST
The following is a table of vulnearbility detectors supported by Gecko and future detectors that will be added when as the AST is impoved and dynamic analysis such as fuzzing is added.
The aim is to create a set of real-life vulnearbilities and examples that will not only serve as a robust development template but also help identify good and bad parctices in Clarity contract development. Contibution of adding new vulnearbilities or examples is welcome.
TODO:
✔️ | Vulnerability | Example/Description |
---|---|---|
(slightly broken) | authentication via tx-sender |
Report , Example: Arkadiko |
✔️ | tx-sender in assert |
|
✔️ | untrusted actions on Stacks wallets (stx-burn? , stx-transfer? ) |
|
✔️ | untrusted actions on fungible tokens (ft-burn? , ft-mint? , ft-transfer? ) |
|
✔️ | untrusted actions on non-fungible tokens (nft-burn? , nft-mint? , nft-transfer? ) |
|
✔️ | untrusted actions on persisted data (map-delete? , map-insert? , map-set? , var-set? ) |
|
✔️ | call inside as-contract |
|
✔️ | use of block-height as time |
|
✔️ | bad use of unwrap-panic |
|
✔️ | precision loss | |
✔️ | TODO comments | |
✔️ | functions not used | |
calls to private functions | ||
return values | ||
dynamic contract calls (through traits) | ||
block time assumption broken on nakamoto release | Farming and stacking core contracts assume block time for the calculation of epoch lengths. However, this assumption is expected to be modified in the next Stacks upgrade (Nakamoto Release), which will reduce block time. | |
rounding errors | ||
panicking on possible error | Using unwrap-panic results in the transaction being finished because of a runtime error when the provided value is an error or a none. The runtime error does not allow the caller to handle that error and act in response. Example: Zest Protocol |
|
as-contract call to unverified principal |
Enclosing a contract call in an as-contract expression makes this internal call to be made on behalf of the caller contract. In the example the tx-sender value is changed to this caller contract. Example: Zest Protocol |
|
signature replay in oracle | Example shows oracle prices are updated with a multi-signature scheme. However, besides validating the signature's content and verifying the signer, the function does not check whether the signatures were already used. Example: Arkadiko | |
race condition | Example shows the interaction between the burning of USDA tokens and the subsequent adjustment of the fragments-per-token variable in the liquidity contract results in lost rewards for the users. Example: Arkadiko | |
free front-running | Example shows fees are charged when minting USDA through open-vault() or update-vault() , if the user adds collateral to the vault. The minting fee is set in the function set-mint-fee() . Example: Arkadiko |
|
'admin' access | ALEX |