Skip to main content

dos-attack

Auto-loaded by logic-auditor agent during Phase 2. Provides detection patterns for: gas griefing, unbounded loops, external call failures, block gas limit exploitation, storage DoS, and liveness failures. Core artifact: Liveness Analysis Map.

Zur Installation springen

Quellinformationen

Repository
BitterSecurity/Vigilo
Letzte Quellaktivität
2. Februar 2026 um 05:07
Erkannte Sprache von SKILL.md
Englisch
Sterne
66
Forks
17

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
dos-attack
description
Auto-loaded by logic-auditor agent during Phase 2. Provides detection patterns for: gas griefing, unbounded loops, external call failures, block gas limit exploitation, storage DoS, and liveness failures. Core artifact: Liveness Analysis Map.
user-invocable
false
# Denial of Service (DoS) Attack Patterns **OWASP SC10:2025** - DoS attacks prevent legitimate users from accessing protocol functionality, potentially locking funds permanently. **2025-2026 Statistics**: DoS vulnerabilities caused protocol freezes affecting $180M+ in locked funds, with gas griefing attacks increasing 45% YoY. --- ## Why DoS Happens (Root Causes) ### Root Cause 1: Unbounded Iteration Loops without gas limits become unusable as data grows. ```solidity // VULNERABLE: Unbounded loop function distributeRewards() external { for (uint256 i = 0; i < holders.length; i++) { // @audit holders can grow unbounded token.transfer(holders[i], rewards[holders[i]]); } } ``` **Attacker's view**: "I'll create thousands of tiny positions. Eventually, no one can call this function." ### Root Cause 2: External Call Dependency Function success depends on external call that attacker can make fail. ```solidity // VULNERABLE: Relies on external transfer success function withdrawAll() external { for (uint256 i = 0; i < users.length; i++) { payable(users[i]).transfer(balances[users[i]]); // @audit One revert blocks all } } ``` **Attacker's view**: "If I'm in the array and my receive() reverts, nobody gets paid." ### Root Cause 3: Storage Slot Exhaustion Unlimited storage growth makes operations cost-prohibitive. ```solidity // VULNERABLE: Unlimited storage growth mapping(address => uint256[]) public userDeposits; function deposit() external payable { userDeposits[msg.sender].push(msg.value); // @audit Array grows forever } function getTotalDeposits(address user) external view returns (uint256) { uint256 total; for (uint256 i = 0; i < userDeposits[user].length; i++) { // @audit View can run out of gas total += userDeposits[user][i]; } return total; } ``` ### Root Cause 4: Block Gas Limit Exploitation Transaction exceeds block gas limit, making it impossible to execute. ```solidity // VULNERABLE: Can exceed block gas limit function processAllPending() external { while (pendingQueue.length > 0) { _processSingle(pendingQueue[0]); pendingQueue.pop(); } } ``` --- ## The Liveness Analysis Map (Core Artifact) For each critical function, document: ``` Function: withdrawAll() ├── External Calls: N calls to user addresses ├── Loop Bound: users.length (unbounded) ├── Gas Estimate: O(n) where n = users count ├── Failure Mode: Single revert blocks all withdrawals ├── Recovery: None - funds permanently locked └── Risk: CRITICAL ``` | Function | Dependency | Bound | Failure Impact | Recovery | |----------|------------|-------|----------------|----------| | distributeRewards | N transfers | Unbounded | Protocol freeze | None | | processQueue | Queue size | Bounded (100) | Temporary delay | Retry | | batchLiquidate | M liquidations | User-controlled | Partial failure | Continue | --- ## Detection Patterns ### Pattern 1: Unbounded Loop DoS **Root Cause**: Unbounded Iteration ```solidity // VULNERABLE: Loop over dynamic array function processAll() external { for (uint256 i = 0; i < items.length; i++) { _process(items[i]); } } ``` **Attack Flow**: 1. Attacker adds many small items to array 2. Array grows to thousands of entries 3. Gas cost exceeds block limit 4. Function becomes uncallable 5. Funds/operations permanently stuck **Search Queries**: ``` Grep("for.*\\.length|while.*\\.length", glob="**/*.sol") Grep("for.*i\\+\\+|for.*i < ", glob="**/*.sol") ``` **Mitigation**: ```solidity // SECURE: Pagination pattern function processRange(uint256 start, uint256 end) external { require(end <= items.length && end - start <= MAX_BATCH); for (uint256 i = start; i < end; i++) { _process(items[i]); } } ``` ### Pattern 2: External Call Failure DoS **Root Cause**: External Call Dependency ```solidity // VULNERABLE: One failure blocks all function refundAll() external { for (uint256 i = 0; i < refundees.length; i++) { (bool success,) = refundees[i].call{value: amounts[i]}(""); require(success, "Refund failed"); // @audit Blocks on any failure } } ``` **Attack Flow**: 1. Attacker enters system with contract that reverts on receive 2. Refund function iterates to attacker's address 3. Attacker's receive() reverts 4. Entire function reverts 5. All refunds blocked **Search Queries**: ``` Grep("\\.call\\{value.*require\\(success", glob="**/*.sol") Grep("\\.transfer\\(|send\\(", glob="**/*.sol") ``` **Mitigation**: ```solidity // SECURE: Pull pattern mapping(address => uint256) public pendingRefunds; function withdraw() external { uint256 amount = pendingRefunds[msg.sender]; pendingRefunds[msg.sender] = 0; (bool success,) = msg.sender.call{value: amount}(""); require(success); } ``` ### Pattern 3: Gas Griefing **Root Cause**: Unchecked Gas Forwarding ```solidity // VULNERABLE: Forwards all gas to untrusted call function executeCallback(address target, bytes calldata data) external { (bool success,) = target.call(data); // @audit Attacker can consume all gas require(success); } ``` **Attack Flow**: 1. Attacker creates contract with expensive fallback 2. Callback executes, consuming all forwarded gas 3. Parent transaction fails or behaves unexpectedly 4. Griefing attack succeeds **Search Queries**: ``` Grep("\\.call\\(|\\.delegatecall\\(", glob="**/*.sol") Grep("gasleft\\(\\)", glob="**/*.sol") ``` **Mitigation**: ```solidity // SECURE: Limit gas forwarded (bool success,) = target.call{gas: 50000}(data); // OR use try/catch try ICallback(target).callback{gas: 50000}(data) {} catch {} ``` ### Pattern 4: Block Stuffing **Risk**: Attacker fills blocks to prevent time-sensitive operations ```solidity // VULNERABLE: Time-sensitive operation function claimAuction() external { require(block.timestamp >= auctionEnd, "Auction ongoing"); require(!claimed, "Already claimed"); claimed = true; // Transfer winning bid... } ``` **Attack Flow**: 1. Attacker sees they're losing auction 2. Before auction ends, attacker submits many high-gas transactions 3. Blocks become full, legitimate claimAuction() can't execute 4. Attacker extends effective auction time 5. Eventually claims at manipulated state **Mitigation**: - Add grace periods for time-sensitive operations - Use commit-reveal for auctions - Allow partial execution ### Pattern 5: Storage Collision DoS **Root Cause**: Unlimited Mapping/Array Growth ```solidity // VULNERABLE: Unlimited storage per user function addOrder(uint256 amount) external { userOrders[msg.sender].push(Order(amount, block.timestamp)); } function cancelAllOrders() external { delete userOrders[msg.sender]; // @audit Gas increases with array size } ``` **Attack Flow**: 1. Attacker creates millions of tiny orders 2. Tries to cancel all (or system tries to process) 3. Gas exceeds limits 4. Operations blocked **Search Queries**: ``` Grep("push\\(|delete.*\\[", glob="**/*.sol") Grep("mapping.*\\[\\]|address.*=>.*\\[\\]", glob="**/*.sol") ``` ### Pattern 6: Return Bomb Attack **Root Cause**: Unbounded Return Data ```solidity // VULNERABLE: Copies all return data function executeCall(address target, bytes calldata data) external returns (bytes memory) { (bool success, bytes memory result) = target.call(data); // @audit result can be huge require(success); return result; } ``` **Attack Flow**: 1. Attacker creates contract returning massive data (e.g., 1MB) 2. Memory expansion costs explode 3. Transaction runs out of gas 4. Call fails unexpectedly **Mitigation**: ```solidity // SECURE: Limit return data or use assembly assembly { let success := call(gas(), target, 0, add(data, 32), mload(data), 0, 0) // Only copy limited return data if needed } ``` --- ## DoS Prevention Checklist ### Loop Safety - [ ] All loops have bounded iterations - [ ] Maximum batch size enforced - [ ] Pagination available for large datasets - [ ] Gas estimation includes worst case ### External Call Safety - [ ] Pull pattern over push pattern - [ ] Individual call failures don't block others - [ ] Gas limits on external calls - [ ] Fallback handling for failed transfers ### Storage Safety - [ ] No unbounded arrays per user - [ ] Cleanup mechanisms exist - [ ] View functions handle large data ### Time Safety - [ ] Grace periods for time-sensitive ops - [ ] No strict time windows attackers can exploit - [ ] Block stuffing resistance --- ## Search Query Reference ``` # Find unbounded loops Grep("for.*\\.length|while.*length", glob="**/*.sol") Grep("for.*i\\+\\+.*\\{", glob="**/*.sol") # Find external calls Grep("\\.call\\{|\\.transfer\\(|\\.send\\(", glob="**/*.sol") Grep("require\\(success", glob="**/*.sol") # Find storage patterns Grep("push\\(|pop\\(|delete", glob="**/*.sol") Grep("mapping.*\\[\\]", glob="**/*.sol") # Find time dependencies Grep("block\\.timestamp|block\\.number", glob="**/*.sol") ``` --- ## Severity Classification ### Critical - Funds permanently locked - Core protocol functions uncallable - No recovery mechanism ### High - Temporary protocol freeze possible - Significant gas griefing impact - User funds at risk ### Medium - View functions can fail - Minor operations blockable - Recovery exists but costly --- ## Rationalization Table (Reject These Excuses) | Excuse | Reality | |--------|---------| | "Array won't grow that large" | Attackers WILL grow it. Assume worst case. | | "Users won't create malicious contracts" | Attackers absolutely will. Every address is suspect. | | "Gas is cheap" | Block gas limit is fixed. 30M gas max per block. | | "We can upgrade if needed" | Funds may be locked BEFORE you can upgrade. | | "This is theoretical" | Akropolis, SpankChain, and others lost millions to DoS. | | "View functions don't matter" | External protocols depend on your views. DoS spreads. |
Auf GitHub ansehen