阿里云主机折上折
  • 微信号
Current Site:Index > Security hardening and vulnerability protection

Security hardening and vulnerability protection

Author:Chuan Chen 阅读数:56331人阅读 分类: Node.js

Security Hardening and Vulnerability Protection

As the most popular web framework in the Node.js ecosystem, the security of Express directly impacts the stability of the entire application. From request validation to dependency management, each aspect requires targeted protective measures.

Request Input Validation

Untreated user input is the most common source of security vulnerabilities. Express's built-in express-validator middleware can effectively filter illegal input:

const { body, validationResult } = require('express-validator');

app.post('/user', 
  body('username').isLength({ min: 5 }).trim().escape(),
  body('email').isEmail().normalizeEmail(),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    // Secure processing logic
  }
);

Special character handling requires particular attention, such as SQL injection protection:

const mysql = require('mysql2/promise');
const pool = mysql.createPool(...);

app.get('/search', async (req, res) => {
  const [rows] = await pool.query(
    'SELECT * FROM products WHERE name = ?', 
    [req.query.keyword] // Use parameterized queries
  );
  res.json(rows);
});

Response Header Security Configuration

Insecure HTTP headers can expose system information or lead to cross-site scripting attacks. The helmet middleware can automatically set secure headers:

const helmet = require('helmet');
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "trusted.cdn.com"]
    }
  },
  hsts: { maxAge: 31536000, includeSubDomains: true }
}));

Example of special configuration for APIs:

app.use((req, res, next) => {
  res.removeHeader('X-Powered-By');
  res.set('X-Content-Type-Options', 'nosniff');
  res.set('X-Frame-Options', 'DENY');
  next();
});

Session Management Security

Session identifiers require special protective measures:

const session = require('express-session');
const RedisStore = require('connect-redis')(session);

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: { 
    secure: true,
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 24 * 60 * 60 * 1000 
  }
}));

Sensitive operations require secondary verification:

app.post('/transfer', requireAuth, (req, res) => {
  if (!req.session.secondFactor) {
    return res.status(403).send('Secondary verification required');
  }
  // Fund transfer logic
});

Dependency Component Security

Third-party library vulnerabilities can become attack vectors. Use npm audit for regular scanning:

npm audit --production

Example of automated vulnerability checking in CI configuration:

# .github/workflows/audit.yml
name: Security Audit
on: [push, pull_request]
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: npm install
      - run: npm audit --audit-level=moderate

File Upload Protection

Malicious file uploads are common attack vectors:

const multer = require('multer');
const upload = multer({
  limits: { fileSize: 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
      return cb(new Error('Only image files are allowed'));
    }
    cb(null, true);
  }
});

app.post('/upload', upload.single('avatar'), (req, res) => {
  // Secure file processing
});

Rate Limiting Protection

Prevent brute-force attacks:

const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  message: 'Too many requests'
});

app.use('/login', limiter);

Dynamic IP blocking strategy:

const failedAttempts = new Map();

app.post('/login', (req, res, next) => {
  const ip = req.ip;
  const attempts = failedAttempts.get(ip) || 0;
  
  if (attempts > 5) {
    return res.status(429).send('Please try again later');
  }
  
  // Validation logic
  if (!valid) {
    failedAttempts.set(ip, attempts + 1);
    setTimeout(() => failedAttempts.delete(ip), 3600000);
  }
});

Error Handling Standards

Improper error messages can leak system details:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ 
    error: 'Internal server error',
    reference: generateErrorId() // Do not expose specific errors
  });
});

Handling differences between production and development environments:

app.use((err, req, res, next) => {
  const response = {
    message: process.env.NODE_ENV === 'development' 
      ? err.message 
      : 'Operation failed'
  };
  res.status(err.status || 500).json(response);
});

Security Logging

Complete audit logs should include:

const winston = require('winston');
const logger = winston.createLogger({
  transports: [
    new winston.transports.File({
      filename: 'security.log',
      level: 'warn',
      format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json()
      )
    })
  ]
});

app.use((req, res, next) => {
  logger.warn({
    method: req.method,
    url: req.originalUrl,
    ip: req.ip,
    userAgent: req.get('User-Agent')
  });
  next();
});

Continuous Security Practices

Automated security testing integration:

// test/security.test.js
const request = require('supertest');
const app = require('../app');

describe('Security Tests', () => {
  it('Should block XSS attacks', async () => {
    const res = await request(app)
      .get('/search?q=<script>alert(1)</script>');
    expect(res.text).not.toContain('<script>');
  });
});

Example of dependency update strategy:

{
  "scripts": {
    "update-check": "npm outdated --json || true",
    "safe-update": "npm update --save --save-exact"
  }
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.