or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

real-world-scenarios.mddocs/examples/

Real-World Scenarios

Comprehensive usage examples for URL Sheriff in production applications.

URL Validation

Basic URL Safety Checking

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

// Safe public URLs - returns true
await sheriff.isSafeURL('https://example.com');
await sheriff.isSafeURL('http://api.github.com/users');

// Unsafe private URLs - throws Error
try {
  await sheriff.isSafeURL('http://127.0.0.1:3000');
} catch (error) {
  console.error(error.message); // "URL uses a private hostname"
}

try {
  await sheriff.isSafeURL('http://localhost:8080');
} catch (error) {
  console.error(error.message); // "URL uses a private hostname"
}

try {
  await sheriff.isSafeURL('http://192.168.1.1');
} catch (error) {
  console.error(error.message); // "URL uses a private hostname"
}

URL Object Support

The library accepts both string URLs and URL objects:

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

// String URL
await sheriff.isSafeURL('https://example.com');

// URL object
const urlObj = new URL('https://example.com');
await sheriff.isSafeURL(urlObj);

// Both work identically

Allow-list Management

Initialize with Allow-list

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  allowList: [
    'localhost',                           // Exact string match
    '127.0.0.1',                          // IP address match
    /^.*\.internal\.company\.com$/,       // Regex pattern match
    /^api-\d+\.staging\.example\.org$/    // Dynamic subdomain pattern
  ]
});

// These URLs are now allowed
await sheriff.isSafeURL('http://localhost:3000');          // true
await sheriff.isSafeURL('http://127.0.0.1:8080');          // true
await sheriff.isSafeURL('https://app.internal.company.com'); // true
await sheriff.isSafeURL('https://api-01.staging.example.org'); // true

Runtime Allow-list Management

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  allowList: ['localhost']
});

// Add more entries at runtime
sheriff.addToAllowList(['trusted-domain.com', /^.*\.safe\.net$/]);
await sheriff.isSafeURL('https://trusted-domain.com'); // true

// Remove entries from allow-list
sheriff.removeFromAllowList(['localhost']);
// Now localhost URLs will be blocked again

// Get current allow-list
const currentAllowList = sheriff.getAllowList();
console.log(currentAllowList); // Array of current entries

Regex Pattern Matching

Complex pattern matching for dynamic hostnames:

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  allowList: [
    // Match any subdomain of internal.example.com
    /^.*\.internal\.example\.com$/,
    // Match numbered API instances
    /^api-\d+\.staging\.example\.org$/,
    // Match specific pattern with port
    /^service-[a-z]+\.dev\.company\.com:\d+$/
  ]
});

await sheriff.isSafeURL('https://app.internal.example.com');        // true
await sheriff.isSafeURL('https://api-01.staging.example.org');     // true
await sheriff.isSafeURL('https://api-99.staging.example.org');     // true
await sheriff.isSafeURL('https://service-auth.dev.company.com:8080'); // true

Scheme Restrictions

Restrict to HTTPS Only

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  allowedSchemes: ['https']
});

// Only HTTPS is allowed
await sheriff.isSafeURL('https://example.com'); // Returns true

try {
  await sheriff.isSafeURL('http://example.com');
} catch (error) {
  console.error(error.message); // "URL scheme 'http' is not allowed"
}

try {
  await sheriff.isSafeURL('ftp://example.com');
} catch (error) {
  console.error(error.message); // "URL scheme 'ftp' is not allowed"
}

Runtime Scheme Management

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  allowedSchemes: ['https']
});

// Update allowed schemes at runtime
sheriff.setAllowedSchemes(['https', 'http']);
await sheriff.isSafeURL('http://example.com'); // Now returns true

// Get current allowed schemes
const schemes = sheriff.getAllowedSchemes(); // Returns ['https', 'http']

// Remove all scheme restrictions
sheriff.clearSchemeRestrictions();
await sheriff.isSafeURL('ftp://example.com'); // Now returns true

Case-Insensitive Scheme Handling

Scheme validation is case-insensitive:

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  allowedSchemes: ['https']
});

// All of these work (case-insensitive)
await sheriff.isSafeURL('https://example.com');  // true
await sheriff.isSafeURL('HTTPS://example.com');  // true
await sheriff.isSafeURL('Https://example.com');  // true

IP Address Validation

Direct IP address checking:

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

// Check if IP addresses are private
sheriff.isPrivateIPAddress('192.168.1.1');      // true - private range
sheriff.isPrivateIPAddress('10.0.0.1');         // true - private range
sheriff.isPrivateIPAddress('127.0.0.1');        // true - loopback
sheriff.isPrivateIPAddress('169.254.1.1');      // true - link-local
sheriff.isPrivateIPAddress('8.8.8.8');          // false - public IP
sheriff.isPrivateIPAddress('1.1.1.1');          // false - public IP

// IPv6 addresses
sheriff.isPrivateIPAddress('::1');              // true - loopback
sheriff.isPrivateIPAddress('fe80::1');          // true - link-local
sheriff.isPrivateIPAddress('2001:4860:4860::8888'); // false - public IP

// IPv4-mapped IPv6 addresses are handled correctly
sheriff.isPrivateIPAddress('::ffff:192.168.1.1'); // true - private
sheriff.isPrivateIPAddress('::ffff:8.8.8.8');     // false - public

DNS Resolution

Using System DNS Resolver

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

const ips = await sheriff.hostnameLookup('example.com');
console.log(ips); // ['93.184.216.34', '2606:2800:220:1:248:1893:25c8:1946']

Using Custom DNS Resolvers

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  dnsResolvers: ['1.1.1.1']
});

const ipsCustom = await sheriff.resolveHostnameViaServers('example.com');
console.log(ipsCustom); // ['93.184.216.34'] - IPv4 only

Multiple DNS Resolvers

Using multiple DNS servers for redundancy:

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff({
  dnsResolvers: ['1.1.1.1', '8.8.8.8', '9.9.9.9']
});

// Will use the configured resolvers in order
await sheriff.isSafeURL('https://example.com');

Integration Patterns

Express.js Middleware

import express from 'express';
import URLSheriff from 'url-sheriff';

const app = express();
const sheriff = new URLSheriff({ allowedSchemes: ['https'] });

app.use(express.json());

app.post('/fetch-url', async (req, res) => {
  const { url } = req.body;
  
  try {
    await sheriff.isSafeURL(url);
    // URL is safe, proceed with fetch
    const response = await fetch(url);
    const data = await response.json();
    res.json(data);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

Request Validation Wrapper

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

async function safeFetch(url: string | URL, options?: RequestInit): Promise<Response> {
  await sheriff.isSafeURL(url);
  return fetch(url, options);
}

// Usage
try {
  const response = await safeFetch('https://api.example.com/data');
  const data = await response.json();
} catch (error) {
  if (error.message.includes('private hostname') || error.message.includes('Invalid URL')) {
    console.error('Security violation:', error.message);
  } else {
    console.error('Fetch error:', error);
  }
}

Batch URL Validation

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

async function validateURLs(urls: string[]): Promise<Map<string, boolean>> {
  const results = new Map<string, boolean>();
  
  await Promise.all(
    urls.map(async (url) => {
      try {
        await sheriff.isSafeURL(url);
        results.set(url, true);
      } catch (error) {
        results.set(url, false);
      }
    })
  );
  
  return results;
}

// Usage
const urls = ['https://example.com', 'http://127.0.0.1', 'https://api.github.com'];
const validationResults = await validateURLs(urls);
validationResults.forEach((isSafe, url) => {
  console.log(`${url}: ${isSafe ? 'SAFE' : 'UNSAFE'}`);
});

Security Best Practices

Production Configuration

import URLSheriff from 'url-sheriff';

// Recommended: Restrict to HTTPS only in production
const productionSheriff = new URLSheriff({
  allowedSchemes: ['https']
});

// Recommended: Use minimal allow-list, only for trusted internal services
const internalSheriff = new URLSheriff({
  allowList: [
    // Only specific trusted domains
    'trusted-api.internal.com',
    // Avoid overly permissive regex patterns
    // BAD: /.*/  (allows everything)
    // GOOD: /^[a-z0-9-]+\.internal\.company\.com$/  (specific pattern)
  ]
});

// Recommended: Validate user-provided URLs before processing
async function validateUserURL(userProvidedURL: string): Promise<boolean> {
  try {
    await productionSheriff.isSafeURL(userProvidedURL);
    return true;
  } catch (error) {
    // Log security event
    console.error('Blocked unsafe URL:', userProvidedURL, error.message);
    return false;
  }
}

Performance Optimization

DNS Resolution Caching

DNS lookups are asynchronous and may introduce latency:

import URLSheriff from 'url-sheriff';

const sheriff = new URLSheriff();

// DNS resolution happens for every domain validation
// Consider caching results for frequently validated domains
const urlCache = new Map<string, boolean>();

async function cachedIsSafeURL(url: string): Promise<boolean> {
  if (urlCache.has(url)) {
    return urlCache.get(url)!;
  }
  
  try {
    const isSafe = await sheriff.isSafeURL(url);
    urlCache.set(url, isSafe);
    return isSafe;
  } catch (error) {
    urlCache.set(url, false);
    throw error;
  }
}

Custom DNS Resolver Performance

import URLSheriff from 'url-sheriff';

// Using fast public DNS resolvers
const fastSheriff = new URLSheriff({
  dnsResolvers: ['1.1.1.1', '8.8.8.8']  // Cloudflare and Google DNS
});

// May be faster than system DNS in some environments
await fastSheriff.isSafeURL('https://example.com');