TypeScript for Cyber Security

Build type-safe security tools with TypeScript — catch bugs at compile time, build reliable scanners, and create production-ready security applications.

Why TypeScript for Security

TypeScript adds static typing to JavaScript, catching bugs before runtime. For security tools where reliability is critical, TypeScript prevents common mistakes that could lead to tool failures or false negatives.

Key Advantages

  • Type safety - Catch errors at compile time, not in production.
  • IntelliSense - Auto-completion and documentation for faster development.
  • Refactoring - Safely refactor large codebases without breaking things.
  • Modern tooling - Used by security tools like nuclei, semgrep, and more.
  • Interfaces - Define clear contracts for security tool components.
Key Benefit

TypeScript is a superset of JavaScript. All valid JavaScript is valid TypeScript. You can gradually add types to existing JS security tools.

TypeScript Basics for Security

TypeScript's type system helps you model security concepts precisely and catch errors before your tools hit production.

Basic Types & Interfaces

typescript
// Basic types
const target: string = "192.168.1.1";
const port: number = 443;
const isOpen: boolean = true;
const openPorts: number[] = [22, 80, 443];

// Interfaces
interface ScanResult {
    ip: string;
    port: number;
    isOpen: boolean;
    service?: string;
    banner?: string;
}

interface Scanner {
    scan(target: string): Promise<ScanResult[]>;
    getName(): string;
}

// Type aliases
type Severity = "Critical" | "High" | "Medium" | "Low" | "Info";
type VulnReport = {
    target: string;
    vulnerabilities: Array<{
        type: string;
        severity: Severity;
        details: string;
    }>;
};

Type Safety for Security

TypeScript's discriminated unions and enums make it easy to model attack types, protocols, and security states in a type-safe way.

Enums & Discriminated Unions

typescript
// Enums for security constants
enum Protocol {
    TCP = "tcp",
    UDP = "udp",
    HTTP = "http",
    HTTPS = "https",
}

// Discriminated unions for attack types
type AttackType =
    | { kind: "sqli"; payload: string; param: string }
    | { kind: "xss"; payload: string; context: string }
    | { kind: "path_traversal"; payload: string };

function describeAttack(attack: AttackType): string {
    switch (attack.kind) {
        case "sqli":
            return `SQLi on ${attack.param}: ${attack.payload}`;
        case "xss":
            return `XSS in ${attack.context}: ${attack.payload}`;
        case "path_traversal":
            return `Path traversal: ${attack.payload}`;
    }
}

Building Security Tools

TypeScript's type system shines when building security tools — interfaces ensure your scanner components have consistent contracts.

Port Scanner

typescript - port_scanner.ts
import net from "net";

interface PortScanResult {
    port: number;
    isOpen: boolean;
    service: string;
    responseTime: number;
}

const SERVICES: Record<number, string> = {
    21: "FTP", 22: "SSH", 25: "SMTP",
    80: "HTTP", 443: "HTTPS", 3306: "MySQL",
    5432: "PostgreSQL", 8080: "HTTP-Alt",
};

function scanPort(host: string, port: number, timeout = 1000): Promise<PortScanResult> {
    return new Promise((resolve) => {
        const start = Date.now();
        const socket = new net.Socket();

        socket.setTimeout(timeout);
        socket.on("connect", () => {
            resolve({
                port,
                isOpen: true,
                service: SERVICES[port] || "Unknown",
                responseTime: Date.now() - start,
            });
            socket.destroy();
        });

        socket.on("timeout", () => {
            resolve({ port, isOpen: false, service: "", responseTime: timeout });
            socket.destroy();
        });

        socket.on("error", () => {
            resolve({ port, isOpen: false, service: "", responseTime: Date.now() - start });
            socket.destroy();
        });

        socket.connect(port, host);
    });
}

async function portScan(host: string, start = 1, end = 1024): Promise<PortScanResult[]> {
    const results: PortScanResult[] = [];
    const batchSize = 100;

    for (let i = start; i <= end; i += batchSize) {
        const batch = Array.from(
            { length: Math.min(batchSize, end - i + 1) },
            (_, idx) => scanPort(host, i + idx)
        );
        const batchResults = await Promise.all(batch);
        results.push(...batchResults.filter((r) => r.isOpen));
    }

    return results.sort((a, b) => a.port - b.port);
}

// Usage
portScan("192.168.1.1").then((open) => {
    open.forEach((r) => console.log(`[+] Port ${r.port}: ${r.service} (${r.responseTime}ms)`));
});
Practice

Build a full vulnerability scanner framework in TypeScript with pluggable scanners, configurable outputs, and type-safe configurations.

Node.js Security Applications

TypeScript on Node.js enables building robust, type-safe security applications for web scanning, header analysis, and more.

Web Security Header Checker

typescript - web_scanner.ts
import https from "https";
import http from "http";

interface WebVuln {
    type: string;
    severity: "Critical" | "High" | "Medium" | "Low";
    path: string;
    detail: string;
}

function fetch(url: string): Promise<{ status: number; headers: Record<string, string>; body: string }> {
    return new Promise((resolve, reject) => {
        const client = url.startsWith("https") ? https : http;
        client.get(url, { timeout: 5000 }, (res) => {
            let body = "";
            res.on("data", (chunk) => (body += chunk));
            res.on("end", () =>
                resolve({ status: res.statusCode || 0, headers: res.headers as any, body })
            );
        }).on("error", reject);
    });
}

async function checkSecurityHeaders(url: string): Promise<WebVuln[]> {
    const vulns: WebVuln[] = [];
    const resp = await fetch(url);
    const required = [
        "x-frame-options", "x-content-type-options",
        "strict-transport-security", "content-security-policy",
    ];

    for (const h of required) {
        if (!resp.headers[h]) {
            vulns.push({ type: "Missing Header", severity: "Medium", path: url, detail: h });
        }
    }

    if (resp.headers["x-powered-by"]) {
        vulns.push({ type: "Info Disclosure", severity: "Low", path: url, detail: `X-Powered-By: ${resp.headers["x-powered-by"]}` });
    }

    return vulns;
}

Resources

  • TypeScript Handbook: typescriptlang.org
  • ts-node: Run TypeScript directly without compilation
  • Zod: Runtime type validation for security inputs
  • Socket.IO Security: Real-time security monitoring