false, 'err' => 'admin pass min 8 chars'], 400); $h = password_hash($pass, PASSWORD_DEFAULT); if ($h === false) nsp_json(['ok' => false, 'err' => 'hash fail'], 500); file_put_contents(nsp_hash_file(), $h . "\n", LOCK_EX); @chmod(nsp_hash_file(), 0600); nsp_vault_write($pass); } function nsp_pass_is_set(): bool { return is_file(nsp_hash_file()) && trim((string)file_get_contents(nsp_hash_file())) !== ''; } function nsp_ok(?string $pass): bool { if ($pass === null || $pass === '') return false; if (!nsp_pass_is_set()) return false; $h = trim((string)file_get_contents(nsp_hash_file())); return $h !== '' && password_verify(trim($pass), $h); } function nsp_require(): void { $p = (string)($_POST['admin_pass'] ?? $_GET['admin_pass'] ?? ''); if (!nsp_ok($p)) nsp_json(['ok' => false, 'err' => 'admin auth'], 401); } function nsp_handle_admin_api(string $api): bool { if (!str_starts_with($api, 'admin_')) return false; if ($api === 'admin_status') { nsp_json(['ok' => true, 'admin_pass_set' => nsp_pass_is_set(), 'site' => 'market', 'vault_hint' => nsp_vault_dir(), 'version' => NSM_VERSION]); } if ($api === 'admin_setup' && ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') { if (nsp_pass_is_set()) nsp_json(['ok' => false, 'err' => 'already set'], 400); nsp_pass_set((string)($_POST['admin_pass'] ?? '')); nsp_json(['ok' => true, 'msg' => 'hash+vault set', 'vault_hint' => nsp_vault_dir()]); } if ($api === 'admin_login' && ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') { nsp_require(); nsp_json(['ok' => true, 'msg' => 'ok', 'site' => 'market', 'vault_hint' => nsp_vault_dir(), 'version' => NSM_VERSION]); } if ($api === 'admin_change_pass' && ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') { nsp_require(); nsp_pass_set((string)($_POST['new_pass'] ?? '')); nsp_json(['ok' => true, 'msg' => 'rotated']); } if ($api === 'admin_get_source' && ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') { nsp_require(); $raw = (string)file_get_contents(__FILE__); nsp_json(['ok' => true, 'bytes' => strlen($raw), 'sha256' => hash('sha256', $raw), 'source' => $raw]); } if ($api === 'admin_put_source' && ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') { nsp_require(); $src = (string)($_POST['source'] ?? ''); if (strlen($src) < 100 || strpos($src, ' false, 'err' => 'bad source'], 400); $bak = __FILE__ . '.bak.' . time(); @copy(__FILE__, $bak); if (file_put_contents(__FILE__, $src, LOCK_EX) === false) nsp_json(['ok' => false, 'err' => 'write failed'], 500); nsp_json(['ok' => true, 'msg' => 'replaced', 'backup' => basename($bak), 'sha256' => hash('sha256', $src)]); } nsp_json(['ok' => false, 'err' => 'unknown admin api'], 404); return true; } function nsp_render_controlpanel(): void { header('Content-Type: text/html; charset=UTF-8'); header('Cache-Control: no-store'); $site = 'Nosignup.Market'; echo ''; echo '' . htmlspecialchars($site) . ' Control
'; echo '

DNA · MARKET · classified gold

'; echo '

' . htmlspecialchars($site) . ' · Control Panel

'; echo '

Site-local renter key. UTTER control of THIS crop (incl. replace index.php). Not OS root. Independent vault. Rent until yearly reset - no refunds. Yearly wipe: panel password re-keys; no site-local NSU wallet on this crop — cashflow rails live on nosignup.trade.

'; echo '
'; echo ''; echo '

Migration: future access = site wallet seed (see trade). For now password panel.

'; echo '
'; echo '

Vault: -

'; echo '

Change password

'; echo '

Source (utter control)

'; echo '
'; echo '

← back

'; exit; } const NSM_VERSION = '2026-07-13k'; const NSM_TTL_SECS = 2592000; // 30 days const NSM_MAX_TITLE = 120; const NSM_MAX_BODY = 1200; const NSM_MAX_CONTACT = 200; const NSM_MAX_PRICE = 40; const NSM_RATE_WINDOW = 600; const NSM_RATE_MAX = 8; const NSM_CATS = ['free', 'items', 'realestate', 'vehicles']; /** Tiny purpose brain: listing_spam - bag-of-words, fail open (no external LLM). */ function nsm_brain_listing_spam(string $title, string $body): array { $t = strtolower($title . ' ' . $body); $hits = []; $bad = [ 'whatsapp' => 0.2, 'telegram.me' => 0.25, 'bit.ly' => 0.2, 'double your' => 0.35, 'guaranteed' => 0.2, 'wire transfer only' => 0.25, 'gift card' => 0.3, 'seed phrase' => 0.45, 'private key' => 0.45, 'act now' => 0.1, '100% free money' => 0.4, 'crypto giveaway' => 0.3, 'click here' => 0.1, ]; $score = 0.0; foreach ($bad as $k => $w) { if ($k !== '' && str_contains($t, $k)) { $score += $w; $hits[] = $k; } } if ($score > 1.0) $score = 1.0; return ['brain' => 'listing_spam', 'score' => round($score, 3), 'hits' => $hits, 'flag' => $score >= 0.55]; } /** Tiny purpose brain: contact_risk - soft-scam tokens in freeform contact; fail open. */ function nsm_brain_contact_risk(string $contact): array { $t = strtolower($contact); $hits = []; $bad = [ 'seed phrase' => 0.5, 'private key' => 0.5, 'mnemonic' => 0.45, 'send btc first' => 0.4, 'wire only' => 0.25, 'gift card' => 0.35, 'western union' => 0.3, 'cashapp only' => 0.15, 'bit.ly' => 0.2, 't.me/' => 0.1, 'wa.me/' => 0.1, 'double your' => 0.35, ]; $score = 0.0; foreach ($bad as $k => $w) { if ($k !== '' && str_contains($t, $k)) { $score += $w; $hits[] = $k; } } if (preg_match('/\b[5-9a-z]{50,}\b/i', $contact)) { $hits[] = 'long_blob'; $score += 0.25; } if ($score > 1.0) { $score = 1.0; } return ['brain' => 'contact_risk', 'score' => round($score, 3), 'hits' => $hits, 'flag' => $score >= 0.5]; } function nsm_json(array $x, int $c = 200): void { http_response_code($c); header('Content-Type: application/json; charset=UTF-8'); header('Cache-Control: no-store'); echo json_encode($x, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; } function nsm_data(): string { $d = __DIR__ . DIRECTORY_SEPARATOR . 'data'; if (!is_dir($d)) @mkdir($d, 0755, true); $ht = $d . DIRECTORY_SEPARATOR . '.htaccess'; if (!is_file($ht)) @file_put_contents($ht, "Require all denied\nDeny from all\n"); $idx = $d . DIRECTORY_SEPARATOR . 'index.html'; if (!is_file($idx)) @file_put_contents($idx, ''); return $d; } function nsm_file(): string { return nsm_data() . DIRECTORY_SEPARATOR . 'listings.jsonl'; } function nsm_ip(): string { $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '0'; if (strpos($ip, ',') !== false) $ip = trim(explode(',', $ip)[0]); return substr(preg_replace('/[^0-9a-fA-F:.\-]/', '', $ip) ?? '0', 0, 64); } function nsm_rate_ok(string $ip): bool { $f = nsm_data() . DIRECTORY_SEPARATOR . 'rate_' . hash('sha256', $ip) . '.json'; $now = time(); $hits = []; if (is_file($f)) { $j = json_decode((string)file_get_contents($f), true); if (is_array($j)) $hits = array_values(array_filter($j, fn($t) => is_int($t) && ($now - $t) < NSM_RATE_WINDOW)); } if (count($hits) >= NSM_RATE_MAX) return false; $hits[] = $now; @file_put_contents($f, json_encode($hits), LOCK_EX); return true; } function nsm_read_all(): array { $path = nsm_file(); if (!is_file($path)) return []; $out = []; $now = time(); $fh = fopen($path, 'rb'); if (!$fh) return []; while (($line = fgets($fh)) !== false) { $line = trim($line); if ($line === '') continue; $j = json_decode($line, true); if (!is_array($j)) continue; $ts = (int)($j['ts'] ?? 0); if ($ts > 0 && ($now - $ts) > NSM_TTL_SECS) continue; $out[] = $j; } fclose($fh); return $out; } function nsm_san(string $s, int $max): string { $s = trim(str_replace(["\r", "\0"], '', $s)); if (function_exists('mb_substr')) return mb_substr($s, 0, $max, 'UTF-8'); return substr($s, 0, $max); } if (isset($_GET['src']) || isset($_GET['download']) || (isset($_GET['api']) && $_GET['api'] === 'src')) { $raw = (string)file_get_contents(__FILE__); header('Content-Type: text/plain; charset=UTF-8'); header('X-Content-Type-Options: nosniff'); header('X-NS-Sha256: ' . hash('sha256', $raw)); if (isset($_GET['download'])) { header('Content-Disposition: attachment; filename="nosignup-market.php"'); } echo $raw; exit; } $api = (string)($_GET['api'] ?? $_POST['api'] ?? ''); if ($api !== '' && str_starts_with($api, 'admin_')) { nsp_handle_admin_api($api); } if ($api !== '' && $api !== 'src') { nsm_data(); if ($api === 'state') { $all = nsm_read_all(); $counts = array_fill_keys(NSM_CATS, 0); foreach ($all as $L) { $c = (string)($L['cat'] ?? ''); if (isset($counts[$c])) $counts[$c]++; } nsm_json(['ok' => true, 'version' => NSM_VERSION, 'ttl_days' => intdiv(NSM_TTL_SECS, 86400), 'counts' => $counts, 'total' => count($all)]); } if ($api === 'list') { $cat = strtolower(preg_replace('/[^a-z]/', '', (string)($_GET['cat'] ?? $_POST['cat'] ?? '')) ?? ''); $q = strtolower(trim((string)($_GET['q'] ?? $_POST['q'] ?? ''))); $all = nsm_read_all(); $out = []; foreach ($all as $L) { if ($cat !== '' && ($L['cat'] ?? '') !== $cat) continue; if ($q !== '') { $hay = strtolower(($L['title'] ?? '') . ' ' . ($L['body'] ?? '') . ' ' . ($L['price'] ?? '') . ' ' . ($L['where'] ?? '')); if (strpos($hay, $q) === false) continue; } $out[] = $L; } usort($out, fn($a, $b) => ((int)($b['ts'] ?? 0)) <=> ((int)($a['ts'] ?? 0))); nsm_json(['ok' => true, 'cat' => $cat, 'n' => count($out), 'listings' => array_slice($out, 0, 200)]); } if ($api === 'post' && ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') { $ip = nsm_ip(); if (!nsm_rate_ok($ip)) nsm_json(['ok' => false, 'err' => 'rate limit - wait a few minutes'], 429); $cat = strtolower(preg_replace('/[^a-z]/', '', (string)($_POST['cat'] ?? '')) ?? ''); if (!in_array($cat, NSM_CATS, true)) nsm_json(['ok' => false, 'err' => 'bad category'], 400); $title = nsm_san((string)($_POST['title'] ?? ''), NSM_MAX_TITLE); $body = nsm_san((string)($_POST['body'] ?? ''), NSM_MAX_BODY); $price = nsm_san((string)($_POST['price'] ?? ''), NSM_MAX_PRICE); $where = nsm_san((string)($_POST['where'] ?? ''), 80); $contact = nsm_san((string)($_POST['contact'] ?? ''), NSM_MAX_CONTACT); if (strlen($title) < 3) nsm_json(['ok' => false, 'err' => 'title too short'], 400); if (strlen($body) < 3) nsm_json(['ok' => false, 'err' => 'description too short'], 400); if ($price === '') $price = ($cat === 'free') ? 'FREE' : 'ASK'; if ($contact === '') nsm_json(['ok' => false, 'err' => 'contact required — put how people reach you on the listing (no account)'], 400); $spam = nsm_brain_listing_spam($title, $body); $cRisk = nsm_brain_contact_risk($contact); // hard block only blatant scam copy; otherwise fail open with soft flag if (($spam['score'] ?? 0) >= 0.9) { nsm_json(['ok' => false, 'err' => 'listing rejected by listing_spam brain', 'brains' => ['listing_spam' => $spam, 'contact_risk' => $cRisk]], 400); } if (($cRisk['score'] ?? 0) >= 0.9) { nsm_json(['ok' => false, 'err' => 'contact rejected by contact_risk brain', 'brains' => ['listing_spam' => $spam, 'contact_risk' => $cRisk]], 400); } $ts = time(); $id = hash('sha256', $ip . '|' . $ts . '|' . $title . '|' . bin2hex(random_bytes(4))); $row = [ 'id' => $id, 'cat' => $cat, 'title' => $title, 'body' => $body, 'price' => $price, 'where' => $where, 'contact' => $contact, 'ts' => $ts, 'exp' => $ts + NSM_TTL_SECS, 'ver' => 1, ]; if (!empty($spam['flag'])) $row['spam'] = $spam; if (!empty($cRisk['flag'])) $row['contact_risk'] = $cRisk; $line = json_encode($row, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); if ($line === false || file_put_contents(nsm_file(), $line . "\n", FILE_APPEND | LOCK_EX) === false) { nsm_json(['ok' => false, 'err' => 'disk'], 500); } nsm_json(['ok' => true, 'listing' => $row, 'msg' => 'posted - lives ~30 days, no account', 'brains' => ['listing_spam' => $spam, 'contact_risk' => $cRisk]]); } nsm_json(['ok' => false, 'err' => 'unknown api'], 404); } $wantPanel = isset($_GET['controlpanel']) || (isset($_SERVER['REQUEST_URI']) && preg_match('#/controlpanel/?(\?|$)#', (string)$_SERVER['REQUEST_URI'])); if ($wantPanel && (string)($_GET['api'] ?? $_POST['api'] ?? '') === '') { nsp_render_controlpanel(); } ?> Nosignup.Market
No account. When you post: put contact on the listing — that is how people reach you. Corners: Free / Items / Real Estate / Vehicles. Cashflow → nosignup.trade