>웹 프론트엔드 >JS 튜토리얼 >웹 개발자를 위한 필수 JavaScript 보안 모범 사례

웹 개발자를 위한 필수 JavaScript 보안 모범 사례

Linda Hamilton
Linda Hamilton원래의
2024-12-21 19:16:15818검색

ssential JavaScript Security Best Practices for Web Developers

저는 웹 개발자로서 JavaScript 애플리케이션을 구축할 때 보안이 가장 중요하다는 것을 배웠습니다. 수년에 걸쳐 저는 웹 애플리케이션의 견고성을 향상시키기 위해 수많은 문제에 직면하고 다양한 전략을 구현했습니다. 이 기사에서는 안전하고 안정적인 웹 애플리케이션을 만드는 데 중요하다고 생각되는 8가지 필수 JavaScript 보안 모범 사례를 공유하겠습니다.

입력 유효성 검사

웹 애플리케이션 보안의 가장 중요한 측면 중 하나는 적절한 입력 유효성 검사입니다. 사용자 입력은 악의적인 행위자의 잠재적인 진입점이 되며, 이를 삭제하고 검증하지 못하면 심각한 보안 취약성이 발생할 수 있습니다. 나는 항상 모든 사용자 입력을 처리하기 전에 철저하게 검사하고 정리하는지 확인합니다.

다음은 JavaScript 코드에서 입력 유효성 검사를 구현하는 방법의 예입니다.

function validateInput(input) {
  // Remove any HTML tags
  let sanitizedInput = input.replace(/<[^>]*>/g, '');

  // Remove any special characters
  sanitizedInput = sanitizedInput.replace(/[^\w\s]/gi, '');

  // Trim whitespace
  sanitizedInput = sanitizedInput.trim();

  // Check if the input is not empty and within a reasonable length
  if (sanitizedInput.length > 0 && sanitizedInput.length <= 100) {
    return sanitizedInput;
  } else {
    throw new Error('Invalid input');
  }
}

// Usage
try {
  const userInput = document.getElementById('userInput').value;
  const validatedInput = validateInput(userInput);
  // Process the validated input
} catch (error) {
  console.error('Input validation failed:', error.message);
}

이 기능은 HTML 태그, 특수 문자를 제거하고 공백을 자릅니다. 또한 입력이 합리적인 길이 내에 있는지 확인합니다. 이러한 검증을 구현함으로써 애플리케이션에서 주입 공격 및 예상치 못한 동작의 위험을 크게 줄일 수 있습니다.

콘텐츠 보안 정책

콘텐츠 보안 정책(CSP)은 XSS(교차 사이트 스크립팅) 공격 및 기타 코드 삽입 공격을 방지하는 데 도움이 되는 강력한 보안 기능입니다. CSP 헤더를 구현함으로써 웹 애플리케이션에서 로드 및 실행이 허용되는 리소스를 제어할 수 있습니다.

Express.js 애플리케이션에서 일반적으로 CSP를 설정하는 방법은 다음과 같습니다.

const express = require('express');
const helmet = require('helmet');

const app = express();

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'", 'https://trusted-cdn.com'],
    styleSrc: ["'self'", 'https://fonts.googleapis.com'],
    imgSrc: ["'self'", 'data:', 'https:'],
    connectSrc: ["'self'", 'https://api.example.com'],
    fontSrc: ["'self'", 'https://fonts.gstatic.com'],
    objectSrc: ["'none'"],
    upgradeInsecureRequests: []
  }
}));

// Your routes and other middleware

이 구성은 신뢰할 수 있는 특정 소스로 리소스 로드를 제한하여 XSS 공격 및 무단 리소스 로드를 완화하는 데 도움이 됩니다.

HTTPS

HTTPS 구현은 클라이언트와 서버 간의 데이터 전송을 보호하는 데 중요합니다. 전송 중인 데이터를 암호화하여 중간자 공격을 방지하고 교환된 정보의 무결성을 보장합니다.

저는 Node.js 애플리케이션에서 개발 환경에서도 항상 HTTPS를 사용합니다. 다음은 HTTPS 서버를 설정하는 방법에 대한 간단한 예입니다.

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();

const options = {
  key: fs.readFileSync('path/to/private-key.pem'),
  cert: fs.readFileSync('path/to/certificate.pem')
};

https.createServer(options, app).listen(443, () => {
  console.log('HTTPS server running on port 443');
});

// Your routes and other middleware

안전한 인증

사용자 계정과 민감한 정보를 보호하려면 보안 인증을 구현하는 것이 중요합니다. 저는 항상 강력한 비밀번호 정책과 OAuth 또는 JWT(JSON Web Tokens)와 같은 안전한 인증 방법을 사용합니다.

다음은 Express.js 애플리케이션에서 JWT 인증을 구현하는 방법의 예입니다.

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

const app = express();
app.use(express.json());

const SECRET_KEY = 'your-secret-key';

// User login
app.post('/login', async (req, res) => {
  const { username, password } = req.body;

  // In a real application, you would fetch the user from a database
  const user = await findUserByUsername(username);

  if (!user || !(await bcrypt.compare(password, user.passwordHash))) {
    return res.status(401).json({ message: 'Invalid credentials' });
  }

  const token = jwt.sign({ userId: user.id }, SECRET_KEY, { expiresIn: '1h' });

  res.json({ token });
});

// Middleware to verify JWT
function verifyToken(req, res, next) {
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).json({ message: 'No token provided' });
  }

  jwt.verify(token, SECRET_KEY, (err, decoded) => {
    if (err) {
      return res.status(401).json({ message: 'Invalid token' });
    }
    req.userId = decoded.userId;
    next();
  });
}

// Protected route
app.get('/protected', verifyToken, (req, res) => {
  res.json({ message: 'Access granted to protected resource' });
});

// Your other routes

이 예에서는 보호된 경로에 대한 토큰을 확인하기 위한 사용자 로그인 및 미들웨어 기능을 포함한 기본 JWT 인증 흐름을 보여줍니다.

사이트 간 요청 위조 방지

Cross-Site Request Forgery(CSRF) 공격은 적절하게 해결되지 않으면 치명적일 수 있습니다. 저는 인증된 사용자를 대신하여 무단 작업을 방지하기 위해 항상 애플리케이션에 CSRF 보호를 구현합니다.

Express.js에서 csurf 미들웨어를 사용하여 CSRF 보호를 일반적으로 구현하는 방법은 다음과 같습니다.

function validateInput(input) {
  // Remove any HTML tags
  let sanitizedInput = input.replace(/<[^>]*>/g, '');

  // Remove any special characters
  sanitizedInput = sanitizedInput.replace(/[^\w\s]/gi, '');

  // Trim whitespace
  sanitizedInput = sanitizedInput.trim();

  // Check if the input is not empty and within a reasonable length
  if (sanitizedInput.length > 0 && sanitizedInput.length <= 100) {
    return sanitizedInput;
  } else {
    throw new Error('Invalid input');
  }
}

// Usage
try {
  const userInput = document.getElementById('userInput').value;
  const validatedInput = validateInput(userInput);
  // Process the validated input
} catch (error) {
  console.error('Input validation failed:', error.message);
}

이 설정은 각 요청에 대해 고유한 CSRF 토큰을 생성하고 양식 제출 시 이를 검증하여 CSRF 공격으로부터 보호합니다.

안전한 쿠키 처리

세션 보안을 유지하고 민감한 정보를 보호하려면 적절한 쿠키 처리가 필수적입니다. 저는 보안을 강화하기 위해 항상 쿠키에 Secure 및 HttpOnly 플래그를 설정합니다.

다음은 Express.js 애플리케이션에서 보안 쿠키를 설정하는 방법의 예입니다.

const express = require('express');
const helmet = require('helmet');

const app = express();

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'", 'https://trusted-cdn.com'],
    styleSrc: ["'self'", 'https://fonts.googleapis.com'],
    imgSrc: ["'self'", 'data:', 'https:'],
    connectSrc: ["'self'", 'https://api.example.com'],
    fontSrc: ["'self'", 'https://fonts.gstatic.com'],
    objectSrc: ["'none'"],
    upgradeInsecureRequests: []
  }
}));

// Your routes and other middleware

이러한 설정을 통해 쿠키는 보안 연결을 통해서만 전송되고, 클라이언트측 스크립트에서는 액세스할 수 없으며, 교차 사이트 요청 공격으로부터 보호됩니다.

타사 라이브러리 관리

타사 라이브러리 관리는 애플리케이션 보안을 유지하는 데 있어 중요한 측면입니다. 저는 항상 종속성을 정기적으로 업데이트하고 알려진 취약점이 있는지 감사하는 것을 중요하게 생각합니다.

종속성 관리를 위한 일반적인 작업 흐름은 다음과 같습니다.

  1. 정기적으로 패키지 업데이트:
const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();

const options = {
  key: fs.readFileSync('path/to/private-key.pem'),
  cert: fs.readFileSync('path/to/certificate.pem')
};

https.createServer(options, app).listen(443, () => {
  console.log('HTTPS server running on port 443');
});

// Your routes and other middleware
  1. 오래된 패키지가 있는지 확인하세요.
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

const app = express();
app.use(express.json());

const SECRET_KEY = 'your-secret-key';

// User login
app.post('/login', async (req, res) => {
  const { username, password } = req.body;

  // In a real application, you would fetch the user from a database
  const user = await findUserByUsername(username);

  if (!user || !(await bcrypt.compare(password, user.passwordHash))) {
    return res.status(401).json({ message: 'Invalid credentials' });
  }

  const token = jwt.sign({ userId: user.id }, SECRET_KEY, { expiresIn: '1h' });

  res.json({ token });
});

// Middleware to verify JWT
function verifyToken(req, res, next) {
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).json({ message: 'No token provided' });
  }

  jwt.verify(token, SECRET_KEY, (err, decoded) => {
    if (err) {
      return res.status(401).json({ message: 'Invalid token' });
    }
    req.userId = decoded.userId;
    next();
  });
}

// Protected route
app.get('/protected', verifyToken, (req, res) => {
  res.json({ message: 'Access granted to protected resource' });
});

// Your other routes
  1. 취약점에 대한 감사 패키지:
const express = require('express');
const csrf = require('csurf');
const cookieParser = require('cookie-parser');

const app = express();

app.use(cookieParser());
app.use(csrf({ cookie: true }));

app.use((req, res, next) => {
  res.locals.csrfToken = req.csrfToken();
  next();
});

app.get('/form', (req, res) => {
  res.send(`
    <form action="/submit" method="POST">
      <input type="hidden" name="_csrf" value="${req.csrfToken()}">
      <input type="text" name="data">
      <button type="submit">Submit</button>
    </form>
  `);
});

app.post('/submit', (req, res) => {
  res.send('Form submitted successfully');
});

app.use((err, req, res, next) => {
  if (err.code !== 'EBADCSRFTOKEN') return next(err);
  res.status(403).send('Invalid CSRF token');
});

// Your other routes and middleware
  1. 가능한 경우 취약점을 수정하세요.
const express = require('express');
const session = require('express-session');

const app = express();

app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true,
  cookie: {
    secure: true, // Ensures the cookie is only sent over HTTPS
    httpOnly: true, // Prevents client-side access to the cookie
    sameSite: 'strict', // Prevents the cookie from being sent in cross-site requests
    maxAge: 3600000 // Sets the cookie expiration time (1 hour in this example)
  }
}));

// Your routes and other middleware

또한 Snyk 또는 npm-check-updates와 같은 도구를 사용하여 이 프로세스를 자동화하고 내 종속 항목의 잠재적인 보안 문제에 대한 경고를 받습니다.

적절한 오류 처리

올바른 오류 처리는 단순히 사용자 경험을 개선하는 것이 아닙니다. 이는 또한 중요한 보안 조치이기도 합니다. 나는 항상 사용자 정의 오류 페이지를 구현하고 오류 메시지에 민감한 정보가 노출되지 않도록 합니다.

다음은 Express.js 애플리케이션에서 오류를 처리하는 방법의 예입니다.

npm update

이 설정은 404(찾을 수 없음) 및 500(내부 서버 오류) 응답에 대한 사용자 정의 오류 페이지를 제공하여 민감한 스택 추적이나 오류 세부 정보가 사용자에게 노출되는 것을 방지합니다.

결론적으로 이러한 8가지 JavaScript 보안 모범 사례를 구현한 결과 웹 애플리케이션의 견고성과 보안이 크게 향상되었습니다. 입력 유효성 검사, 콘텐츠 보안 정책, HTTPS, 보안 인증, CSRF 보호, 보안 쿠키 처리, 타사 라이브러리 관리 및 적절한 오류 처리에 중점을 두어 더욱 안전하고 안정적인 애플리케이션을 만들 수 있었습니다.

보안은 지속적인 프로세스라는 점에 유의하는 것이 중요합니다. 새로운 위협이 등장하고 기술이 발전함에 따라 우리는 경계심을 늦추지 않고 보안 관행을 지속적으로 업데이트해야 합니다. 정기적인 보안 감사, 침투 테스트 및 최신 보안 동향에 대한 최신 정보를 얻는 것은 모두 강력한 보안 상태를 유지하는 과정의 일부입니다.

보안은 단지 이러한 관행을 한 번 구현하고 잊어버리는 것이 아닙니다. 이는 개발의 모든 측면에서 보안 우선 사고방식을 배양하는 것입니다. 우리가 작성하는 모든 코드 줄, 구현하는 모든 기능, 우리가 내리는 모든 결정은 보안이라는 렌즈를 통해 보아야 합니다.

JavaScript 애플리케이션의 보안을 최우선으로 생각하여 사용자와 데이터를 보호할 뿐만 아니라 제품에 대한 신뢰도를 구축합니다. 데이터 침해와 사이버 공격이 점점 더 흔해지는 오늘날의 디지털 환경에서 강력한 보안 전략은 있으면 좋을 뿐만 아니라 절대적으로 필요한 것입니다.

개발자로서 우리는 기능적이고 사용자 친화적인 애플리케이션뿐만 아니라 안전한 애플리케이션도 개발할 책임이 있습니다. 이러한 모범 사례를 따르고 지속적으로 보안에 대해 교육함으로써 우리는 모두를 위한 보다 안전하고 안전한 웹 생태계에 기여할 수 있습니다.


우리의 창조물

저희 창작물을 꼭 확인해 보세요.

인베스터 센트럴 | 투자자 중앙 스페인어 | 중앙 독일 투자자 | 스마트리빙 | 시대와 메아리 | 수수께끼의 미스터리 | 힌두트바 | 엘리트 개발자 | JS 학교


우리는 중간에 있습니다

테크 코알라 인사이트 | Epochs & Echoes World | 투자자중앙매체 | 수수께끼 미스터리 매체 | 과학과 신기원 매체 | 현대 힌두트바

위 내용은 웹 개발자를 위한 필수 JavaScript 보안 모범 사례의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.