48 lines
1.9 KiB
PHP
48 lines
1.9 KiB
PHP
<?php
|
|
// opus-arch-api-fuzzer.php — Cap 3 Auto-discovery APIs (Doctrine 89)
|
|
// Scans /api/*.php for undocumented actions via response analysis
|
|
header('Content-Type: application/json');
|
|
|
|
$action = $_GET['action'] ?? 'scan';
|
|
$api_dir = '/var/www/html/api';
|
|
$cache_file = '/opt/weval-ops/api-fuzzer-cache.json';
|
|
|
|
if ($action === 'scan') {
|
|
$limit = (int)($_GET['limit'] ?? 10);
|
|
$files = glob($api_dir . '/opus5-*.php');
|
|
$files = array_slice($files, 0, $limit);
|
|
$discoveries = [];
|
|
foreach ($files as $f) {
|
|
$base = basename($f);
|
|
// Probe common actions
|
|
foreach (['status', 'health', 'list', 'stats', 'info', 'version'] as $probe) {
|
|
$url = 'http://127.0.0.1/api/' . $base . '?action=' . $probe;
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>3, CURLOPT_HTTPHEADER=>['Host: weval-consulting.com']]);
|
|
$out = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
if ($code == 200 && $out && strpos($out, '404') === false && strlen($out) > 20) {
|
|
$j = json_decode($out, true);
|
|
if ($j && ($j['ok'] ?? false)) {
|
|
$discoveries[] = ['file'=>$base, 'action'=>$probe, 'size'=>strlen($out)];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
file_put_contents($cache_file, json_encode(['ts'=>date('c'), 'discoveries'=>$discoveries], JSON_PRETTY_PRINT));
|
|
echo json_encode(['ok'=>true, 'scanned'=>count($files), 'discovered'=>count($discoveries), 'results'=>$discoveries]);
|
|
exit;
|
|
}
|
|
|
|
if ($action === 'list') {
|
|
if (file_exists($cache_file)) {
|
|
echo file_get_contents($cache_file);
|
|
} else {
|
|
echo json_encode(['ok'=>false, 'error'=>'no scan yet, run action=scan']);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
echo json_encode(['ok'=>false, 'actions'=>['scan','list']]);
|