Documentation

Security

Loly includes built-in security features to help you build secure applications.

Rate Limiting

Loly Framework includes integrated rate limiting to protect your application from abuse and DDoS attacks. Configure it in loly.config.ts:

loly.config.ts
import { ServerConfig } from "@lolyjs/core";

export const config = (env: string): ServerConfig => {
  return {
    rateLimit: {
      windowMs: 15 * 60 * 1000, // 15 minutes (time window)
      max: 100,                  // Maximum requests per IP (general routes)
      apiMax: 100,               // Maximum for API routes (optional, uses max if not specified)
      strictMax: 5,              // Maximum for strict routes (auth, etc.)
      strictPatterns: [          // Patterns that automatically use strictMax
        "/api/auth/**",
        "/api/login/**",
        "/api/register/**",
        "/api/password/**",
        "/api/reset/**",
      ],
    },
  };
};

Automatic Rate Limiting: The framework automatically applies rate limiting:

  • Routes matching strictPatterns use strictMax (default: 5 requests/15min)
  • Other routes use max (default: 100 requests/15min)
  • If a route already has a manual rate limiter, the automatic one is not applied

Note: Rate limiting is automatically applied in production. To enable it in development, set ENABLE_RATE_LIMIT=true.

You can also apply rate limiting manually in specific routes:

app/api/sensitive/route.ts
import { strictRateLimiter, defaultRateLimiter, createRateLimiter } from "@lolyjs/core";
import type { ApiMiddleware } from "@lolyjs/core";

// Use predefined rate limiter
export const beforeApi: ApiMiddleware[] = [
  strictRateLimiter, // 5 requests / 15 min
  // ... other middlewares
];

// Or create a custom one
const customLimiter = createRateLimiter({
  windowMs: 60 * 1000, // 1 minute
  max: 10,             // 10 requests per minute
  message: "Too many requests, please slow down.",
});

export const beforeApi: ApiMiddleware[] = [
  customLimiter,
];

Validation

Validate request data using Zod schemas:

import { validate } from "@lolyjs/core";
import { z } from "zod";

const userSchema = z.object({
  email: z.string().email(),
  age: z.number().int().min(0).max(150),
  name: z.string().min(1).max(100),
});

export async function POST(ctx: ApiContext) {
  try {
    const data = validate(userSchema, ctx.req.body);
    // Data is validated and type-safe
    const user = await createUser(data);
    return ctx.Response({ user }, 201);
  } catch (error) {
    // Validation errors are automatically handled
    return ctx.Response({ error: "Validation failed" }, 400);
  }
}

Sanitization

Route parameters and query strings are automatically sanitized to prevent XSS attacks. You can also manually sanitize data:

import { sanitizeString, sanitizeObject } from "@lolyjs/core";

// Sanitize a string
const clean = sanitizeString(userInput);

// Sanitize an object
const cleanData = sanitizeObject({
  name: userInput.name,
  description: userInput.description,
});

Security Headers

Helmet is configured by default with CSP (Content Security Policy) and nonce support. Security headers are automatically applied to all responses.

The framework includes:

  • Content Security Policy (CSP)
  • X-Frame-Options
  • X-Content-Type-Options
  • X-XSS-Protection
  • Strict-Transport-Security (HSTS)
  • Referrer-Policy