AUTO-SEC AUDITOR
Resources/Documentation

Documentation

Introduction

TROUT (AUTO-SEC-AUDITOR) adalah audit otomatis pasif untuk website: dia meng-crawl domain target dengan permintaan GET layaknya browser biasa (tidak ada exploit, brute force, atau serangan aktif), lalu menganalisis hasil crawl untuk tiga hal:

  • Security findings — header keamanan yang hilang, endpoint/form yang terekspos, library JS usang, dsb.
  • QC Otomatis — skor SEO, Performance (via PageSpeed Insights), dan Content/Link (broken link, aksesibilitas dasar).
  • Request Inspector — data mentah tiap request yang dikirim crawler (header, body preview, ukuran, status).

Karena sifatnya pasif dan read-only, TROUT dimaksudkan untuk domain milik sendiri atau yang sudah diberi izin tertulis — bukan pentest aktif.

Quick Start

Alur pemakaian dari nol sampai dapat laporan lengkap:

1
Passive Security Scan
Dari halaman Overview, masukkan domain/URL target lalu centang konfirmasi kepemilikan/izin. Ini men-trigger startScanAction (Server Action, bukan endpoint REST) yang membuat scan ID lalu jalan di background.
2
QC Otomatis (SEO / Performance / Content)
Di /qc, pilih modul yang mau dijalankan lalu submit. Ini memanggil POST /api/qc/scan yang mengembalikan qcId, dan progres bisa diikuti lewat GET /api/qc/[id]/stream (SSE).
3
Inspeksi Request Mentah
Buka /requests untuk lihat semua scan yang pernah jalan, lalu masuk ke /requests/[id] untuk lihat header, preview HTML, dan cURL tiap request yang dilakukan crawler.
4
Baca Laporan
Findings keamanan (severity, endpoint, evidence) ada di /scan/[id], sedangkan ringkasan semua scan + severity breakdown ada di /history.

Crawler

Mesin crawl-nya terbagi dua file: lib/crawler.ts (fetch dengan header ala Chrome asli, deteksi Cloudflare challenge, parsing HTML via cheerio/linkedom) dan lib/site-crawler.ts (loop BFS antar halaman, maksimal 50 halaman unik / MAX_CRAWL_URLS, kedalaman default 3 level).

Total request HTTP per crawl dibatasi oleh RequestBudget di lib/rate-limit.ts — default maksimal 100 request, dengan jeda 500ms antar request untuk Passive Scan (300ms untuk QC) supaya tidak membebani server target.

// lib/rate-limit.ts
export class RequestBudget {
  constructor(private readonly max = 100, private readonly delayMs = 500) {}
  canSpend(n = 1): boolean { return this.used + n <= this.max; }
}

// dipakai di lib/scan-runner.ts
const budget = new RequestBudget(100, 500);

Redis Schema

Semua akses Redis wajib lewat lib/redis.ts getKv() otomatis pilih Upstash (REST) atau node-redis (TCP) tergantung env yang tersedia, plus fallback in-memory kalau keduanya kosong (dev lokal tanpa Redis).

import { getKv } from "@/lib/redis";
const kv = getKv();

// Passive Security Scan
trout:scan:{id}:meta   // ScanState tanpa logs (domain, status, findings, pages[], ...)
trout:scan:{id}:logs   // list ScanLogEvent (rpushJSON, dipakai stream SSE)

// QC Otomatis
trout:qc:{id}:meta            // QcState tanpa logs
trout:qc:{id}:logs            // list QcLogEvent
trout:qc:{id}:result:{module} // hasil per-modul: seo | perf | content

// Cooldown / rate limit
trout:cooldown:{userKey}:{hostname}

kv.getJSON(key) / kv.setJSON(key, val, ttl) / kv.keys(pattern)

Scoring System

QC Otomatis punya 3 modul independen, masing-masing menghasilkan skor 0–100:

  • SEO lib/qc-seo.ts: title/meta description, heading structure, alt text gambar, canonical, dsb.
  • Performance lib/qc-performance.ts: Google PageSpeed Insights (butuh GOOGLE_PAGESPEED_API_KEY), dengan fallback estimasi dari ukuran HTML kalau API tidak tersedia.
  • Content / Link lib/qc-content.ts: broken link (dari request budget yang sama), aksesibilitas dasar.

Skor akhir yang ditampilkan di dashboard adalah rata-rata dari modul yang dijalankan (skip modul yang tidak dipilih).

Deployment

Environment variables yang dipakai (lihat .env.example):

# Wajib salah satu — Upstash direkomendasikan untuk Vercel
UPSTASH_REDIS_REST_URL=...
UPSTASH_REDIS_REST_TOKEN=...

# Alternatif: Redis TCP biasa (dev lokal / self-host)
REDIS_URL=redis://...

# Opsional — kalau kosong, modul Performance pakai estimasi fallback
GOOGLE_PAGESPEED_API_KEY=...

Tanpa Redis sama sekali, app tetap jalan pakai in-memory store (cocok untuk demo lokal singkat) — tapi data hilang tiap restart server dan tidak ke-share antar serverless instance di production.