Netlify Edge 작업자를 사용하여 정적 자산에서 HTML 전용 헤더를 제거하여 헤더 팽창을 줄입니다.

훌륭한 서비스인 Netlify에서 내 사이트를 호스팅합니다. _headers 파일 또는 netlify.toml 구성 파일을 통해 사용자 정의 헤더를 추가하는 것이 정말 쉽습니다.

오래 전에 내 사이트에 몇 가지 보안 관련 헤더를 추가했습니다.

[[headers]]
  for = "/*"
  [headers.values]
    x-frame-options = "DENY"
    x-xss-protection = "1; mode=block"

/* 패턴을 사용하여 Netlify에서 오는 모든 요청에 ​​이러한 헤더를 추가하여 모든 기반을 다뤘는지 확인했습니다. 아무도 아기를 iframe의 내 웹사이트 구석에 두지 않습니다!

오늘 밤으로 돌아가서 정말 멋진webhint browser extension을 통해 웹사이트를 운영하고 있는데 개선할 수 있는 영역이 보입니다. 'Unneeded HTTP Headers':

Unneeded HTTP Headers
no-html-only-headers warns against responding with HTTP headers that are not needed for non-HTML (or non-XML) resources



흥미로운! 많은 보안 관련 헤더는 이미지, 글꼴, 스크립트 등을 포함하는 응답이 아니라 문서 수준(HTML 응답)에서만 전송되어야 합니다. HTML이 아닌 응답에 대해 이러한 헤더를 보내는 것은 바이트를 낭비하고 응답을 조금 더 크게 만드는 것 외에는 아무것도 아닙니다.

그래서 우리는 그것들을 바로 제거합니까?



아, 그렇게 빠르지는 않습니다...Netlify에서 /*와 같은 일반 경로 패턴으로 헤더를 설정하면 나중에 해당 헤더를 실행 취소하는 쉬운 방법이 없는 것 같습니다.

일반적으로 이 상황에서는 /* 보다 더 구체적인 규칙을 사용하지만 HTML 응답과 관련되기는 어렵습니다.

한 가지 조언이 /*.html 와 같은 규칙을 사용하는 것인 big Netlify support thread about this 가 있지만 대부분의 방문자가 https://wolstenhol.me/ 대신 https://wolstenhol.me/index.html 와 같은 URL을 사용하여 페이지에 액세스하는 것을 좋아하기 때문에 그다지 유용하지 않습니다.

지원 스레드가 Netlify Edge Functions 이전 날짜임을 기억할 때까지 포기할 준비를 하고 있었습니다.

에지 기능으로 구출!



Edge Functions은 '가장자리'(이 경우 Netlify의 CDN 인프라)에서 실행되는 작은 스크립트입니다. 이를 통해 과거에는 Nginx 또는 Apache 구성을 작성해야 했던 작업을 수행할 수 있으며 Netlify와 같은 무료 호스팅의 정적 사이트에 대해 작업을 수행할 수 있습니다. 이를 통해 웹사이트에서 사용자에게 가는 네트워크 요청을 프로그래밍 방식으로 가로채고 이를 수정할 수 있습니다. 이것이 바로 여기서 우리가 해야 할 일입니다.

Netlify Edge 함수를 사용하여 방문자 중 한 명에게 전송되는 HTML이 아닌 응답을 함수가 포착하는 경우 HTML 전용 보안 헤더를 제거해 보겠습니다.

우선 netlify.toml 파일에서 Netlify가 생성하려는 함수에 대해 알려주도록 구성해 보겠습니다.

[[edge_functions]]
  path = "/*"
  function = "strip-non-html-headers"


그런 다음 아래 JavaScript 함수를 이 위치netlify/edge-functions/strip-non-html-headers.js에 있는 저장소의 파일에 추가하십시오.

함수의 주석을 읽고 의견에 질문이 있으면 알려주십시오.

export default async (request, context) => {
  // Get the response.
  const response = await context.next();
  const contentType = response.headers.get('content-type');

  // If we can't work out the content-type, or it's HTML
  // then we had better leave the security headers in place.
  // In this case we can return the untransformed response.
  if (!contentType || contentType.startsWith('text/html')) {
    return response;
  }

  // This is a list of headers that only need to be sent on
  // HTML/document responses. It's a waste of bytes to send
  // them on fonts, images, etc as they will have no effect.
  const htmlOnlyHeaders = [
    'content-security-policy',
    'x-content-security-policy',
    'x-ua-compatible',
    'x-webkit-csp',
    'x-xss-protection',
    'x-frame-options',
    // https://webhint.io/docs/user-guide/hints/hint-no-html-only-headers
  ];

  // Loop over the headers of our response…
  response.headers.forEach((value, key, object) => {
    // Some of the security headers make sense to apply to
    // JavaScript files, so we do a bit of logic here:
    if (contentType.startsWith('text/javascript') && (key === 'content-security-policy' || key === 'x-content-security-policy')) {
      // In case of a JavaScript file, Content-Security-Policy and X-Content-Security-Policy
      // can be ignored since CSP is also relevant to workers.
      context.log(`Ignoring as a JS file`);
      return;
    }

    // Otherwise, we delete any headers from the object that
    // contains them within the response.
    if (htmlOnlyHeaders.includes(key)) {
      object.delete(key);
    }
  });

  return response;
};


두 개의 헤더가 실제로 JavaScript 파일에 유용하다는 사실이 밝혀지면서 약간 복잡해졌지만 나머지 함수는 의미가 있기를 바랍니다.

브라우저의 개발자 도구에서 curl( curl -I https://example.com/your-file-name.jpg )과 같은 도구 또는 네트워크 탭을 사용하여 글꼴 파일이나 이미지와 같은 항목에서 x-xss-protection와 같은 헤더가 누락되었는지 확인할 수 있습니다.

이는 에지 기능/에지 작업자가 개발자에게 제공하는 강력함과 유연성을 보여주는 좋은 예입니다.Netlify가 구성 시스템에 '이전에 설정된 헤더 재정의' 옵션을 추가할 때까지 기다리는 대신 일부 표준 웹 API( Response interface that we are using in the Edge Function is part of the Fetch family of APIs)를 사용하여 자체적으로 CDN의 응답을 프로그래밍 방식으로 변경할 수 있습니다.

좋은 웹페이지 즐겨찾기