npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

farrow-helmet

v0.1.0

Published

Security middleware for Farrow HTTP applications that helps secure your web apps by setting various HTTP security headers

Readme

farrow-helmet

npm version TypeScript License: MIT Test Status

A security middleware for Farrow HTTP applications that helps secure your web apps by setting various HTTP security headers.

farrow-helmet is a TypeScript-first security middleware designed specifically for the Farrow HTTP framework, providing comprehensive protection against common web vulnerabilities.

中文文档 | English

Table of Contents

Features

🛡️ Comprehensive Security Headers - Automatically sets essential security headers
🔧 Highly Configurable - Fine-tune security policies for your needs
TypeScript First - Full type safety and IntelliSense support
🚀 Minimal Dependencies - Lightweight wrapper around proven helmet.js
🧪 Well Tested - 21+ test cases covering all functionality
📦 Farrow Optimized - Designed specifically for Farrow HTTP framework

Quick Start

npm install farrow-helmet
import { Http, Response } from 'farrow-http'
import { helmet } from 'farrow-helmet'

const app = Http()

// Apply security middleware
app.use(helmet())

app.get('/').use(() => Response.json({ 
  message: '🛡️ Secured with farrow-helmet!' 
}))

app.listen(3000)

That's it! Your Farrow application is now protected with essential security headers.

Installation

# npm
npm install farrow-helmet

# yarn  
yarn add farrow-helmet

# pnpm
pnpm add farrow-helmet

Prerequisites:

  • Node.js 16+
  • TypeScript 4.5+
  • farrow-http 2.x

Basic Usage

Default Protection

Apply helmet with sensible defaults:

import { helmet } from 'farrow-helmet'

app.use(helmet())

This automatically enables:

  • Content type sniffing protection
  • Clickjacking protection
  • XSS filtering (modern approach)
  • Referrer policy controls
  • Download security for IE
  • Cross-domain policy restrictions

Custom Configuration

Customize security policies to fit your needs:

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "https://cdn.example.com"],
      styleSrc: ["'self'", "'unsafe-inline'"]
    }
  },
  hsts: {
    maxAge: 31536000, // 1 year
    includeSubDomains: true,
    preload: true
  }
}))

Security Headers

farrow-helmet sets the following security headers by default:

| Header | Default Value | Purpose | |--------|---------------|---------| | X-Content-Type-Options | nosniff | Prevents MIME type sniffing attacks | | X-Frame-Options | SAMEORIGIN | Prevents clickjacking attacks | | X-XSS-Protection | 0 | Modern XSS protection (disables legacy filter) | | Referrer-Policy | no-referrer | Controls referrer information leakage | | X-Download-Options | noopen | Prevents IE from executing downloads | | X-Permitted-Cross-Domain-Policies | none | Restricts Flash/PDF cross-domain access |

Additional Available Headers

Configure these headers with custom options:

  • Content Security Policy (CSP) - Prevents XSS and injection attacks
  • HTTP Strict Transport Security (HSTS) - Enforces HTTPS connections
  • X-DNS-Prefetch-Control - Controls DNS prefetching
  • Expect-CT - Certificate transparency enforcement
  • Feature-Policy / Permissions-Policy - Controls browser features

Configuration

Content Security Policy (CSP)

Protect against XSS and injection attacks:

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "https://trusted-cdn.com"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
      fontSrc: ["'self'", "https:", "data:"],
      objectSrc: ["'none'"],
      baseUri: ["'self'"],
      formAction: ["'self'"],
      frameAncestors: ["'none'"],
      blockAllMixedContent: [],
      upgradeInsecureRequests: []
    }
  }
}))

HTTP Strict Transport Security (HSTS)

Force HTTPS connections:

app.use(helmet({
  hsts: {
    maxAge: 31536000,        // 1 year in seconds
    includeSubDomains: true, // Apply to all subdomains
    preload: true           // Enable HSTS preloading
  }
}))

Environment-Specific Configuration

Configure different policies for different environments:

const isDevelopment = process.env.NODE_ENV === 'development'
const isProduction = process.env.NODE_ENV === 'production'

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: [
        "'self'", 
        ...(isDevelopment ? ["'unsafe-eval'", "'unsafe-inline'"] : [])
      ],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "blob:"]
    }
  },
  hsts: isProduction ? {
    maxAge: 63072000, // 2 years
    includeSubDomains: true,
    preload: true
  } : false, // Disable HSTS in development
  
  // Report CSP violations in development
  contentSecurityPolicyReportOnly: isDevelopment
}))

Disabling Specific Headers

Disable headers you don't need:

app.use(helmet({
  xFrameOptions: false,           // Disable X-Frame-Options
  contentSecurityPolicy: false,  // Disable CSP
  xContentTypeOptions: false     // Disable X-Content-Type-Options
}))

Advanced Usage

Integration with Other Middleware

Proper middleware ordering is crucial for security:

const app = Http({ logger: true })

// 1. Error handling (first)
app.use(async (req, next) => {
  try {
    return await next(req)
  } catch (error) {
    console.error('Request failed:', error)
    return Response.status(500).json({ 
      error: 'Internal server error' 
    })
  }
})

// 2. Security headers (early)
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"]
    }
  }
}))

// 3. CORS (after security)
import { cors } from 'farrow-cors'

app.use(cors({
  origin: 'https://trusted-domain.com',
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization']
}))

// 4. Authentication
app.use(authenticationMiddleware)

// 5. Business logic
app.get('/api/data').use(() => Response.json({ data: [] }))

Router-Specific Security

Apply different security policies to different routes:

import { Router } from 'farrow-http'

// Public API - Restrictive CSP
const publicRouter = Router()
publicRouter.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'none'"],
      scriptSrc: ["'none'"],
      styleSrc: ["'none'"],
      imgSrc: ["'none'"]
    }
  }
}))
publicRouter.get('/status').use(() => Response.json({ status: 'ok' }))

// Admin panel - More permissive
const adminRouter = Router()
adminRouter.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'"],
      styleSrc: ["'self'", "'unsafe-inline'"]
    }
  }
}))
adminRouter.get('/dashboard').use(() => Response.html(dashboardHTML))

// Mount routers
app.route('/api').use(publicRouter)
app.route('/admin').use(adminRouter)

Dynamic Security Policies

Adjust policies based on request context:

const dynamicHelmet = (req: RequestInfo, next: any) => {
  const isAPIRequest = req.pathname.startsWith('/api')
  const isAdminRequest = req.pathname.startsWith('/admin')
  
  let helmetConfig = {}
  
  if (isAPIRequest) {
    helmetConfig = {
      contentSecurityPolicy: {
        directives: {
          defaultSrc: ["'none'"]
        }
      }
    }
  } else if (isAdminRequest) {
    helmetConfig = {
      contentSecurityPolicy: {
        directives: {
          defaultSrc: ["'self'"],
          scriptSrc: ["'self'", "'unsafe-inline'"]
        }
      }
    }
  }
  
  return helmet(helmetConfig)(req, next)
}

app.use(dynamicHelmet)

Best Practices

1. Start with Strict Policies

Begin with restrictive policies and gradually relax them:

// Start strict
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'none'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'"],
      imgSrc: ["'self'"]
    }
  }
}))

// Then add exceptions as needed
// scriptSrc: ["'self'", "https://trusted-cdn.com"]

2. Use CSP Report-Only Mode for Testing

Test CSP policies without breaking functionality:

app.use(helmet({
  contentSecurityPolicyReportOnly: {
    directives: {
      defaultSrc: ["'self'"],
      reportUri: ['/csp-report']
    }
  }
}))

// Handle CSP reports
app.post('/csp-report').use((req) => {
  console.log('CSP Violation:', req.body)
  return Response.status(204).empty()
})

3. Environment-Specific Security

const securityConfig = {
  development: {
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "'unsafe-eval'", "'unsafe-inline'"],
        styleSrc: ["'self'", "'unsafe-inline'"]
      }
    },
    hsts: false
  },
  production: {
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'"],
        styleSrc: ["'self'"]
      }
    },
    hsts: {
      maxAge: 31536000,
      includeSubDomains: true,
      preload: true
    }
  }
}

app.use(helmet(securityConfig[process.env.NODE_ENV] || securityConfig.production))

4. Monitor and Log Security Headers

app.use(helmet())

app.use((req, next) => {
  const response = next(req)
  
  // Log security-relevant requests
  if (req.pathname.includes('..') || req.pathname.includes('<script>')) {
    console.warn('Suspicious request:', {
      ip: req.headers['x-forwarded-for'] || 'unknown',
      userAgent: req.headers['user-agent'],
      path: req.pathname
    })
  }
  
  return response
})

Examples

Complete Production Setup

import { Http, Response, Router } from 'farrow-http'
import { helmet } from 'farrow-helmet'
import { createContext } from 'farrow-pipeline'

const app = Http({
  logger: {
    ignoreIntrospectionRequestOfFarrowApi: true
  }
})

// Security configuration
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      baseUri: ["'self'"],
      blockAllMixedContent: [],
      fontSrc: ["'self'", "https:", "data:"],
      frameAncestors: ["'self'"],
      imgSrc: ["'self'", "data:"],
      objectSrc: ["'none'"],
      scriptSrc: ["'self'"],
      scriptSrcAttr: ["'none'"],
      styleSrc: ["'self'", "https:", "'unsafe-inline'"],
      upgradeInsecureRequests: []
    }
  },
  hsts: {
    maxAge: 63072000, // 2 years
    includeSubDomains: true,
    preload: true
  }
}))

// CORS for API
import { cors } from 'farrow-cors'

const apiRouter = Router()
apiRouter.use(cors({
  origin: 'https://yourdomain.com',
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  exposedHeaders: ['X-Total-Count', 'X-Request-ID']
}))

apiRouter.get('/users').use(() => {
  return Response.json({ users: [] })
})

app.route('/api').use(apiRouter)

// Static files with security
app.serve('/static', './public')

// Health check
app.get('/health').use(() => {
  return Response.json({ 
    status: 'healthy',
    timestamp: new Date().toISOString()
  })
})

const port = process.env.PORT || 3000
app.listen(port, () => {
  console.log(`🛡️ Secure server running on http://localhost:${port}`)
})

CSP Violation Reporting

import { ObjectType, String, Optional, Any } from 'farrow-schema'

class CSPReport extends ObjectType {
  documentUri = String
  referrer = Optional(String)
  violatedDirective = String
  originalPolicy = String
  blockedUri = Optional(String)
  sourceFile = Optional(String)
  lineNumber = Optional(Number)
  columnNumber = Optional(Number)
}

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      reportUri: ['/csp-report']
    }
  }
}))

app.post('/csp-report', { body: { "csp-report": CSPReport } }).use((req) => {
  const report = req.body["csp-report"]
  
  console.warn('CSP Violation:', {
    uri: report.documentUri,
    directive: report.violatedDirective,
    blocked: report.blockedUri,
    source: report.sourceFile,
    line: report.lineNumber,
    timestamp: new Date().toISOString()
  })
  
  // Store in database or send to monitoring service
  // await logCSPViolation(report)
  
  return Response.status(204).empty()
})

API Reference

helmet(options?: HelmetOptions): HttpMiddleware

The main helmet function that returns a Farrow HTTP middleware.

HelmetOptions

All options are optional and match the helmet.js API:

interface HelmetOptions {
  contentSecurityPolicy?: CSPOptions | false
  hsts?: HSTSOptions | false
  xContentTypeOptions?: boolean
  xDnsPrefetchControl?: { allow?: boolean } | false
  xDownloadOptions?: boolean
  xFrameOptions?: XFrameOptionsOptions | false
  xPermittedCrossDomainPolicies?: XPermittedCrossDomainPoliciesOptions | false
  xPoweredBy?: boolean
  xXssProtection?: boolean
  referrerPolicy?: ReferrerPolicyOptions | false
  // ... and more
}

CSPOptions

Content Security Policy configuration:

interface CSPOptions {
  directives?: {
    defaultSrc?: string[]
    scriptSrc?: string[]
    styleSrc?: string[]
    imgSrc?: string[]
    fontSrc?: string[]
    objectSrc?: string[]
    baseUri?: string[]
    formAction?: string[]
    frameAncestors?: string[]
    // ... and more
  }
  reportOnly?: boolean
  reportUri?: string[]
}

HSTSOptions

HTTP Strict Transport Security configuration:

interface HSTSOptions {
  maxAge?: number          // Max age in seconds
  includeSubDomains?: boolean
  preload?: boolean
}

For complete API documentation, see the helmet.js documentation.

Testing

farrow-helmet comes with comprehensive tests covering all functionality:

# Run tests
npm test

# Run tests in watch mode  
npm run test:watch

# Run tests with coverage
npm run test:coverage

Testing Your Security Setup

Test your security headers:

import { Http } from 'farrow-http'
import { helmet } from 'farrow-helmet'
import request from 'supertest'

const app = Http()
app.use(helmet())
app.get('/test').use(() => Response.json({ message: 'test' }))

describe('Security Headers', () => {
  it('should set security headers', async () => {
    const response = await request(app.server())
      .get('/test')
      .expect(200)

    expect(response.headers['x-content-type-options']).toBe('nosniff')
    expect(response.headers['x-frame-options']).toBe('SAMEORIGIN')
    expect(response.headers['x-xss-protection']).toBe('0')
    expect(response.headers['referrer-policy']).toBe('no-referrer')
  })
})

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/AisonSu/farrow-helmet.git
cd farrow-helmet

# Install dependencies
pnpm install

# Run tests
pnpm test

# Build the project
pnpm build

Reporting Issues

Please report security issues privately to [email protected].

For other issues, please use the GitHub issue tracker.

License

MIT © Aison

Related


Security Notice: While farrow-helmet helps secure your applications by setting security headers, it's not a silver bullet. Always follow security best practices, keep your dependencies updated, and consider additional security measures like input validation, authentication, and authorization.