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 '
Admin password ';
echo '
Login First-time setup ';
echo '
Migration: future access = site wallet seed (see trade). For now password panel.
';
echo '
';
echo '
Vault: -
';
echo '
Change password Update
';
echo '
Source (utter control) Load Save ';
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
Options
Mirrors
Donate
Classifieds · No Signup
Nosignup.Market
Corners Free / Items / Real Estate / Vehicles List Swipe or post - contact on the listing - ~30 day life Cashflow Faucet and donate rails on nosignup.trade Ephemeral No local NSU wallet - yearly panel re-key
Experimental · unmoderated · trust local · enter at your own risk.
ENTER
x Mirrors Free tributaries. Host a copy · help the network · zero cut · no price power. Tributaries earn from the faucet a market-dictated price per day . One .php file — drop on any PHP host.
↓ Download this file
Known public roots:
Close
x Donate One .php file. No build step. Optional — never required.
BITCOIN bc1qqnu6n0jztxl4f6krv7klradghle09uhyu7uymz
MONERO 8Ab24DppUvcdtHfm7K8gTqdBTmPCBiak1GwxgPm1C3osYVQL2QdC1C8GMwggKF77RKKzDgP2R8E3VH8ifetsKms5AqkVyVg
LITECOIN ltc1qlpdy8qzejcmjdn6vwarpyz8djdlk780w4qkwyp
Tap address to copy · also see nosignup.trade faucet/rails
Close
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