Skip to content

Commit 62b6407

Browse files
author
root
committed
v5: Add MakerDAO auth pattern detection for mint/burn access control
1 parent 82aece3 commit 62b6407

3 files changed

Lines changed: 325 additions & 258 deletions

File tree

server/ai/report-generator.js

Lines changed: 118 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,68 +20,132 @@ function parseJsonObject(value) {
2020

2121
function buildAiPrompt({ targetType, targetUrl, sourceKind, level, findings, vulnerabilities, toolsUsed, artifact, datasetExamples, language = "ru" }) {
2222
return [
23-
'Ты — senior аудитор смарт-контрактов. Пиши на русском. Изучи базу знаний ниже.',
23+
'Ты — senior аудитор смарт-контрактов с 10-летним опытом работы в Web3 security.',
2424
'',
25-
'=== БАЗА ЗНАНИЙ: РЕАЛЬНЫЕ ЭКСПЛОЙТЫ ===',
25+
'=== РЕАЛЬНЫЕ ЭКСПЛОЙТЫ С ПРИМЕРАМИ КОДА ===',
2626
'',
27-
'REENTRANCY:',
28-
'- The DAO (2016, $60M): fallback() вызвал withdraw() повторно до обновления баланса',
29-
'- Cream Finance (2021, $130M): reentrancy через токен ERC-777',
30-
'- Fei Protocol (2022, $80M): reentrancy через flashloan + deposit',
31-
'- Исправление: использовать ReentrancyGuard или CEI (Checks-Effects-Interactions)',
27+
'1. REENTRANCY (The DAO, 2016, $60M):',
28+
' УЯЗВИМЫЙ КОД:',
29+
' ```solidity',
30+
' function withdraw(uint _amount) public {',
31+
' require(balances[msg.sender] >= _amount);',
32+
' msg.sender.call{value: _amount}(""); // ВНЕШНИЙ ВЫЗОВ ДО ОБНОВЛЕНИЯ',
33+
' balances[msg.sender] -= _amount;',
34+
' }',
35+
' ```',
36+
' ИСПРАВЛЕНИЕ:',
37+
' ```solidity',
38+
' function withdraw(uint _amount) public {',
39+
' require(balances[msg.sender] >= _amount);',
40+
' balances[msg.sender] -= _amount; // СНАЧАЛА ОБНОВЛЕНИЕ',
41+
' (bool success,) = msg.sender.call{value: _amount}("");',
42+
' require(success, "Transfer failed");',
43+
' }',
44+
' ```',
3245
'',
33-
'ACCESS CONTROL:',
34-
'- Poly Network (2021, $600M): отсутствие проверки прав на вызов функции',
35-
'- Wormhole (2022, $325M): отсутствие валидации guardian подписей',
36-
'- Qubit Finance (2022, $80M): устаревшая функция без модификатора',
37-
'- Исправление: onlyOwner, RBAC, multi-sig, временные блокировки',
46+
'2. ACCESS CONTROL (Poly Network, 2021, $600M):',
47+
' УЯЗВИМЫЙ КОД: function mint(address to, uint amount) public { _mint(to, amount); }',
48+
' ИСПРАВЛЕНИЕ: function mint(address to, uint amount) public onlyOwner { _mint(to, amount); }',
3849
'',
39-
'DELEGATECALL:',
40-
'- Parity Wallet (2017, $150M): delegatecall в незащищённую библиотеку с selfdestruct',
41-
'- Исправление: использовать immutable для адреса библиотеки, проверять код',
50+
'3. INTEGER OVERFLOW (BeautyChain BEC, 2018, $900M):',
51+
' УЯЗВИМЫЙ КОД:',
52+
' ```solidity',
53+
' function batchTransfer(address[] _receivers, uint256 _value) public {',
54+
' uint256 amount = _receivers.length * _value; // ПЕРЕПОЛНЕНИЕ',
55+
' require(balances[msg.sender] >= amount);',
56+
' balances[msg.sender] -= amount;',
57+
' }',
58+
' ```',
59+
' ИСПРАВЛЕНИЕ:',
60+
' ```solidity',
61+
' using SafeMath for uint256;',
62+
' function batchTransfer(address[] _receivers, uint256 _value) public {',
63+
' uint256 amount = _receivers.length.mul(_value); // БЕЗОПАСНО',
64+
' require(balances[msg.sender] >= amount);',
65+
' balances[msg.sender] = balances[msg.sender].sub(amount);',
66+
' }',
67+
' ```',
4268
'',
43-
'INTEGER OVERFLOW:',
44-
'- PoWH Coin (2018): арифметическое переполнение через оператор сложения-присваивания',
45-
'- BeautyChain (2018): переполнение uint256 через умножение',
46-
'- Исправление: Solidity 0.8+ или SafeMath библиотека',
69+
'4. DELEGATECALL (Parity Wallet, 2017, $150M):',
70+
' УЯЗВИМЫЙ КОД:',
71+
' ```solidity',
72+
' address lib = 0x...;',
73+
' (bool success,) = lib.delegatecall(data); // НЕПРОВЕРЕННЫЙ БИБЛИОТЕКА',
74+
' ```',
75+
' ИСПРАВЛЕНИЕ:',
76+
' ```solidity',
77+
' address immutable lib = 0x...; // immutable АДРЕС',
78+
' require(isValidLibrary(lib), "Invalid library");',
79+
' (bool success,) = lib.delegatecall(data);',
80+
' require(success, "Delegatecall failed");',
81+
' ```',
4782
'',
48-
'ORACLE/MANIPULATION:',
49-
'- Inverse Finance (2022, $15M): манипуляция ценовым оракулом через flashloan',
50-
'- Cream Finance (2021): манипуляция ценой через низколиквидный пул',
51-
'- Исправление: TWAP (средневзвешенная цена), множественные источники цен',
83+
'5. UNCHECKED CALL (Lendf.Me, 2020, $25M):',
84+
' УЯЗВИМЫЙ КОД: (bool success,) = addr.call{value: amount}("");',
85+
' ИСПРАВЛЕНИЕ:',
86+
' ```solidity',
87+
' (bool success,) = addr.call{value: amount}("");',
88+
' require(success, "ETH transfer failed");',
89+
' ```',
5290
'',
53-
'FLASHLOAN ATTACKS:',
54-
'- PancakeBunny (2021, $200M): манипуляция ценой через flashloan + mint',
55-
'- Harvest Finance (2020, $33M): flashloan для арбитража кривой',
56-
'- Исправление: проверка slippage, минимальное время между действиями',
91+
'6. FRONT-RUNNING (Bancor, 2020):',
92+
' УЯЗВИМЫЙ КОД:',
93+
' ```solidity',
94+
' function swap(uint amount) public {',
95+
' require(balances[msg.sender] >= amount); // ПРОВЕРКА',
96+
' uint price = getPrice(); // ЦЕНА МОЖЕТ ИЗМЕНИТЬСЯ',
97+
' balances[msg.sender] -= amount; // ОБНОВЛЕНИЕ ПОЗДНО',
98+
' }',
99+
' ```',
100+
' ИСПРАВЛЕНИЕ:',
101+
' ```solidity',
102+
' function swap(uint amount, uint minOut) public {',
103+
' require(balances[msg.sender] >= amount);',
104+
' balances[msg.sender] -= amount; // СНАЧАЛА ОБНОВЛЕНИЕ',
105+
' uint price = getPrice();',
106+
' require(price >= minOut, "Slippage too high");',
107+
' }',
108+
' ```',
57109
'',
58-
'UNCHECKED RETURN VALUES:',
59-
'- Lendf.Me (2020, $25M): не проверен результат .call()',
60-
'- Исправление: require(success, "Call failed")',
110+
'=== ВАЖНЫЕ ПРАВИЛА АУДИТА ===',
61111
'',
62-
'FRONT-RUNNING:',
63-
'- Bancor (2020): фронт-раннинг через публичный mempool',
64-
'- Исправление: commit-reveal схема, лимит slippage',
112+
'1. Checks-Effects-Interactions: Всегда обновляй состояние ДО внешних вызовов',
113+
'2. Используй OpenZeppelin контракты (ReentrancyGuard, Ownable, SafeMath)',
114+
'3. Не доверяй tx.origin, используй msg.sender',
115+
'4. Проверяй возвращаемые значения низкоуровневых call',
116+
'5. Для дедлайнов используй блоки (block.timestamp + 30min buffer)',
117+
'6. Добавляй zero-address проверки для всех трансферов',
118+
'7. Используй immutable для неизменяемых адресов',
65119
'',
66-
'LOGIC ERRORS:',
67-
'- bZx (2020, $8M): логическая ошибка в проверке состояния',
68-
'- Yearn Finance (2021, $11M): ошибка в расчёте доли',
69-
'- Исправление: тщательное тестирование, формальная верификация',
120+
'=== ТВОЯ ЗАДАЧА ===',
70121
'',
71-
'=== ЗАДАЧА ===',
72-
'Проанализируй находки ниже и для каждой:',
73-
'1. Конкретный уязвимый код из контракта',
74-
'2. Исправленный код (Solidity)',
75-
'3. Сценарий атаки с суммой потенциального ущерба',
76-
'4. Вероятность эксплуатации (Low/Medium/High)',
77-
'5. Похожий реальный эксплойт из базы знаний',
122+
'Проанализируй находки детекторов ниже и сгенерируй JSON отчёт.',
78123
'',
79-
'Формат: JSON с ключами executiveSummary, criticalRisks, remediationRoadmap, trainingSignals',
80-
'Пиши ТОЛЬКО на русском. Никаких общих фраз.',
124+
'ТРЕБОВАНИЯ К ОТВЕТУ:',
125+
'- executiveSummary: 2-3 предложения, укажи общий риск (Low/Medium/High/Critical)',
126+
'- criticalRisks: массив строк, КАЖДАЯ строка содержит (1) описание уязвимости, (2) ссылку на реальный эксплойт, (3) пример суммы ущерба',
127+
'- remediationRoadmap: массив строк, КАЖДАЯ строка содержит (1) что исправить, (2) КОНКРЕТНЫЙ КОД исправления (Solidity)',
128+
'- trainingSignals: массив строк, 2-3 предложения как улучшить автоматическое обнаружение',
81129
'',
82-
`Контракт: ${targetUrl || 'артефакт'} (${targetType}, ${sourceKind})`,
83-
`Уровень: ${level} | Risk Score: ${vulnerabilities?.riskScore || 'N/A'}/100`,
84-
`Находки: ${JSON.stringify((findings || []).slice(0, 25))}`,
130+
'ФОРМАТ ОТВЕТА - ТОЛЬКО JSON, НИКАКОГО ДРУГОГО ТЕКСТА:',
131+
'{',
132+
' "executiveSummary": "string",',
133+
' "criticalRisks": ["string", "string"],',
134+
' "remediationRoadmap": ["string", "string"],',
135+
' "trainingSignals": ["string", "string"]',
136+
'}',
137+
'',
138+
`=== ДАННЫЕ ДЛЯ АНАЛИЗА ===`,
139+
`Тип цели: ${targetType}`,
140+
`Цель: ${targetUrl || 'загруженный контракт'}`,
141+
`Тип исходного кода: ${sourceKind}`,
142+
`Уровень сканирования: ${level}`,
143+
`Оценка риска: ${vulnerabilities?.riskScore || 'N/A'}/100`,
144+
`Инструменты: ${JSON.stringify(toolsUsed || ['chainscout'])}`,
145+
`Находки детекторов (${findings?.length || 0}):`,
146+
`${JSON.stringify((findings || []).slice(0, 30), null, 2)}`,
147+
'',
148+
'ВНИМАНИЕ: remediationRoadmap ДОЛЖЕН содержать примеры кода. Никаких общих фраз типа "убедитесь в безопасности".',
85149
].join('\n');
86150
}
87151

@@ -91,11 +155,12 @@ async function getOpenRouterAiAnalysis({ prompt, maxTokens }) {
91155
messages: [
92156
{
93157
role: 'system',
94-
content: 'Ты — senior Web3 аудитор. Пиши на русском. Даёшь КОНКРЕТНЫЕ исправления с ПРИМЕРАМИ КОДА Solidity/Rust. Никаких общих советов — только точный код.',
158+
content: 'Ты — senior Web3 аудитор. Отвечаешь ТОЛЬКО валидным JSON. remediationRoadmap обязательно содержит конкретный код Solidity. Никогда не используй общие советы без примеров кода.',
95159
},
96160
{ role: 'user', content: prompt },
97161
],
98162
maxTokens,
163+
temperature: 0.3,
99164
});
100165
const content = response?.choices?.[0]?.message?.content || response?.output?.[0]?.content || '';
101166
return parseJsonObject(String(content));
@@ -108,12 +173,12 @@ async function getOpenAIAiAnalysis({ prompt, maxTokens }) {
108173
messages: [
109174
{
110175
role: 'system',
111-
content: 'You are a senior Web3 security auditor. You provide SPECIFIC, ACTIONABLE recommendations with code examples.',
176+
content: 'You are a senior Web3 security auditor. Return ONLY valid JSON. remediationRoadmap MUST contain concrete Solidity code examples.',
112177
},
113178
{ role: 'user', content: prompt },
114179
],
115180
max_tokens: maxTokens,
116-
temperature: 0.2,
181+
temperature: 0.3,
117182
}, {
118183
headers: { Authorization: `Bearer ${OPENAI_API_KEY}`, 'Content-Type': 'application/json' },
119184
timeout: 25000,
@@ -124,7 +189,7 @@ async function getOpenAIAiAnalysis({ prompt, maxTokens }) {
124189

125190
async function generateAiAnalysis({ targetType, targetUrl, sourceKind, level, findings, vulnerabilities, toolsUsed, artifact, datasetExamples }) {
126191
const prompt = buildAiPrompt({ targetType, targetUrl, sourceKind, level, findings, vulnerabilities, toolsUsed, artifact, datasetExamples });
127-
const maxTokens = 2000;
192+
const maxTokens = 2500;
128193

129194
if (process.env.OPENROUTER_API_KEY) {
130195
try {

0 commit comments

Comments
 (0)