diff --git a/website/app/ai-built-startup-security/page.tsx b/website/app/ai-built-startup-security/page.tsx new file mode 100644 index 0000000..eee97d7 --- /dev/null +++ b/website/app/ai-built-startup-security/page.tsx @@ -0,0 +1,350 @@ +import type { Metadata } from 'next'; +import Link from 'next/link'; +import { ArrowRight, Boxes, FileSearch, ShieldAlert, TerminalSquare } from 'lucide-react'; +import CopyButton from '@/components/CopyButton'; +import { getSiteUrl } from '@/lib/config'; +import { buildDocsStructuredData, toJsonLd } from '@/lib/structured-data'; + +const PAGE_PATH = '/ai-built-startup-security'; + +const installCommand = + 'curl -fsSL https://raw.githubusercontent.com/trydirect/stackdog/main/install.sh | sudo bash'; + +const envSnippet = `STACKDOG_PHPSHELL_ENABLED=true +STACKDOG_PHPSHELL_PATHS=/var/www +STACKDOG_PHP_VERSION_CHECK_ENABLED=true +STACKDOG_LOG_SOURCES=/var/log/nginx/access.log,/var/log/apache2/access.log,\\ +/var/log/apache2/error.log,/var/log/nginx/error.log +STACKDOG_IP_BAN_ENABLED=true +STACKDOG_IP_BAN_MAX_RETRIES=5 +STACKDOG_IP_BAN_FIND_TIME_SECS=300 +STACKDOG_IP_BAN_BAN_TIME_SECS=1800 +STACKDOG_IP_BAN_PROTECT_LOCAL_IPS=true +STACKDOG_IP_BAN_ALLOWLIST=`; + +const verifyCommand = 'curl -s http://127.0.0.1:5000/api/alerts'; + +const checklist = [ + 'StackdogApp installed and stackdog serve running.', + 'Every web root in STACKDOG_PHPSHELL_PATHS.', + 'Host access and error logs in STACKDOG_LOG_SOURCES.', + 'Allowlist filled before the first false positive, not after.', + 'PHP builds checked against the fixed releases; upgrade scheduled.', + 'If you cannot upgrade immediately: session.upload_progress.enabled = 0 is the interim mitigation the alert names.' +]; + +const earlyAttacks = [ + { + icon: ShieldAlert, + title: 'Scanners', + body: 'Automated crawlers probing for known shells, admin panels and misconfigurations. On our own shop, eight scanner addresses ended up in the firewall DROP list in one morning, tagged rules and database records agreeing on all eight. Nobody attacked us specifically; that is just what a public IP receives.' + }, + { + icon: TerminalSquare, + title: 'Brute force', + body: 'Repeated SSH and login failures from rented infrastructure. The oldest attack on the internet, and it works on weekend servers because nobody configured a ban threshold.' + }, + { + icon: FileSearch, + title: 'Exploit probes', + body: 'Requests that try known flaws against whatever you happen to be running. PHP2Shell (CVE-2026-109618, CVE-2026-109619) is the current example: two bugs in the PHP interpreter itself, fixed on 22 October 2026 in 8.2.35, 8.3.36, 8.4.27 and 8.5.12. Every build below those numbers is being probed.' + }, + { + icon: Boxes, + title: 'The quiet win: a webshell', + body: 'When an attack lands, it lands quietly. One file in an upload directory, executing whatever its owner sends it. It looks like any other PHP file until you read it and correlate it with the access log.' + } +]; + +const detections = [ + { + title: 'Webshell scanning with ban correlation', + body: 'Every sniff pass reads PHP files in your web roots and scores them: request input reaching eval or system, eval of decoded data, markers of known shell families. A flagged file is an alert; the request that drives it from the access log is what gets banned.' + }, + { + title: 'PHP2Shell version check', + body: 'Which PHP builds predate 8.2.35, 8.3.36, 8.4.27 or 8.5.12, on the host and inside every running container, from package databases and the official images’ own PHP_VERSION. Distribution packages get a "check your vendor" alert, because backports keep the old version number.' + }, + { + title: 'PHP2Shell attempt bans', + body: 'The exploit’s footprint is a request that runs PHP out of memory while it is still being parsed. Apache logs it as in Unknown on line 0 with the client address; behind nginx, php-fpm dies and nginx logs the dead upstream. Both lines feed the ban engine.' + }, + { + title: 'Worker crash watch', + body: 'php-fpm and Apache workers dying repeatedly on SIGSEGV, SIGBUS or SIGABRT raise an alert.' + }, + { + title: 'SSH and login brute force', + body: 'The same pattern fail2ban users know: repeated failures, threshold, temporary ban. Container logs are discovered on their own.' + } +]; + +const limits = [ + 'It does not patch your code or your interpreter. Upgrading PHP and your dependencies stays your job; the free PHP2Shell check tells you where the patch belongs.', + 'The ban flags requests after they happen. Treat it as a backstop for scanners and repeat attempts, not a promise about a first, fast request.', + 'Bans are IPv4 only today. If your traffic is IPv6-heavy, that matters.', + 'It reads the logs it is pointed at. Host logs not listed in STACKDOG_LOG_SOURCES are invisible to it.' +]; + +export const metadata: Metadata = { + title: 'Security for AI-Built Startups: Surviving the First Weeks', + description: + 'Apps built with AI ship in days; the security operations layer does not. What early attacks look like on a fresh server, and how StackdogApp covers webshells, PHP2Shell and brute force without a single hand-written rule.', + keywords: [ + 'AI-built app security', + 'startup server security', + 'webshell detection', + 'PHP2Shell', + 'fail2ban alternative', + 'StackdogApp' + ], + alternates: { + canonical: PAGE_PATH + }, + openGraph: { + title: 'Security for AI-Built Startups — StackdogApp', + description: + 'The code arrives in days. The attacks arrive too. What early traffic looks like and how to cover it without writing detection rules.', + url: getSiteUrl() + PAGE_PATH + }, + twitter: { + title: 'Security for AI-Built Startups — StackdogApp', + description: + 'The code arrives in days. The attacks arrive too. What early traffic looks like and how to cover it.' + } +}; + +function CodeSample({ code, label }: { code: string; label: string }) { + return ( +
+
+

{label}

+ +
+
+        {code}
+      
+
+ ); +} + +export default function AiBuiltStartupSecurityPage() { + return ( +
+