메타데이터 및 격리 정책 가져오기

메타데이터 헤더를 얻는 모든 정보와 각종 클라이언트 공격을 막기 위한 격리 전략을 어떻게 실현하는지 알아보기.너는 원문 here을 읽을 수 있다.

무엇이 메타데이터 헤더를 가져오는 것입니까?


Fetch metadata Header는 비교적 새로운 브라우저 보안 기능으로 웹 응용 프로그램에서 전대미문의 클라이언트 공격을 막을 수 있습니다.
제목의 용도는 매우 간단하다.그것들은 웹 서버 HTTP 요청이 발생한 상하문을 알려줍니다.

하나의 예


짐이 왔다.그는 쿠키 b.example을 사용하여 SessionId=123에 로그인했다.

가령 한 사이트가 a.example에서 b.example에서 사진 한 장을 불러왔다고 가정한다.

메타데이터 헤더를 가져오지 않았습니다.


fetch 메타데이터 헤더가 존재하기 전에 Jim이 a.example을 열었을 때 웹 서버에서 누군가가 Jim의 쿠키로 그림을 불러오는 것을 보았습니다.

HTTP 레벨에서는 다음과 같습니다.
GET /cat.jpg HTTP/1.1
Host: b.example
Cookie: SessionId=123
서버는 a.example 또는 b.example 에서 Jim 세션 ID가 있는 이미지를 로드하는지 여부를 알 수 없습니다.

가져오기 메타데이터 헤더 사용


메타데이터 헤더 가져오기가 지원되는 경우 브라우저는 요청 시 웹 서버에 추가 정보를 보냅니다.

HTTP 레벨에서는 다음과 같습니다.
GET /cat.jpg HTTP/1.1
Host: b.example
Cookie: SessionId=123
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site
이번 브라우저는 웹 서버에 다음과 같은 세 가지 새로운 사항을 알려 줍니다.
  • 요청은 이미지 요소에서 온 것입니다.
  • 에서 요청한 mode(네비게이션이 아닌 자원 부하).
  • 이 요청은 다른 사이트에서 온 것입니다.
  • 실제로 요청에는 네 번째 일이 담겨 있다.Sec-Fetch-User 헤더가 부족하다는 것은 요청이 사용자의 상호작용으로 인해 발생한 것이 아니라는 것을 의미한다.

    메타데이터 헤더를 가져오면 어떤 공격을 방지할 수 있습니까?


    메타데이터 헤더를 가져오면 거의 모든 사이트 공격을 방지할 수 있습니다.이러한 작업은 다음과 같습니다.
  • XSS (Cross-Site Scripting) Attacks
  • CSRF (Cross-Site Request Forgery) Attacks
  • Various XS-leaks
  • XSSI (Cross-Site Script Inclusion) Attacks
  • Spectre
  • Clickjacking
  • 메타데이터 헤드 가져오기


    이 시스템은 네 개의 HTTP 요청 헤더로 구성되어 있다.

    Sec 검색 사이트

    Sec-Fetch-Site마리는 웹 서버 요청이 동일한 소스, 동일한 사이트 또는 완전히 다른 사이트에서 온 것인지를 알려줍니다.다음 값 중 하나를 사용할 수 있습니다.
  • same-origin: 요청은 같은 출처, 즉 호스트, 포트와 방안이 같다.기원의 의미 here을 더 많이 읽을 수 있습니다.
  • same-site: 다른 원본에서 요청을 받았지만 같은 사이트에서 왔습니다. 이것은 같은 등록 가능한 영역의 하위 영역의 브라우저 행화입니다.예를 들어 https://a.example.comhttps://b.example.com은 같은 장소로 여겨지지만 출처가 다르다.
  • cross-site: 요청은 완전히 다른 사이트에서 왔습니다.예를 들어 www.google.comwww.facebook.com은 전체 사이트로 간주됩니다.
  • none: 요청은 어느 사이트에서 온 것이 아닙니다.사용자가 책갈피를 열거나 URL 표시줄에 수동으로 입력하거나 다른 프로그램의 링크를 열 때 발생합니다.
  • 초 추출 모드

    Sec-Fetch-Mode은 웹 서버 요청에 대해 mode을 알려줍니다.다음 값 중 하나를 사용할 수 있습니다.
  • same-origin: 브라우저가 같은 원본에 요청을 하고 있습니다.대상이 다른 소스에서 온 경우 이 모드를 사용하는 요청이 실패합니다.
  • no-cors: 브라우저가 다른 원본에 요청을 하고 있지만 응답을 읽거나 열거되지 않은 HTTP 술어나 헤더를 사용하지 않으려고 합니다.
  • cors: 브라우저에서 CORS(소스 간 공유) 요청을 실행합니다.당신은 더 많은 CORS here에 대한 정보를 읽을 수 있습니다.
  • navigate: 브라우저가 한 페이지에서 다른 페이지로 이동하고 있습니다. 예를 들어 링크를 누르거나 방향을 바꾸거나 책갈피를 열 때.
  • Sec Fetch Dest

    Sec-Fetch-Dest은 웹 서버가 요청한 목적지, 즉 어떤 곳에서 자원을 기다리고 있는지 알려줍니다.위의 예에서 자원을 탑재하는 것은 <img> 요소이기 때문에 목표는 image이다.
    몇 가지 가능한 값은 다음과 같습니다.
  • empty: fetch() 또는 XHR를 통해 리소스를 로드하는 경우
  • document: 최고급 내비게이션에서 자원을 불러올 때.
  • image: 자원이 <img> 표시에 불러올 때.
  • worker: new Worker(...)을 통해 리소스를 로드하는 경우
  • iframe: 자원이 <iframe>에 불러올 때.
  • 이 값은 외부 자원을 탑재할 수 있는 모든 요소이므로 audio, audioworklet, embed, font, frame, manifest, object, paintworklet, report, script, serviceworker, sharedworker, style, track, video, xslt 등이 될 수 있다.

    Sec 사용자 가져오기

    Sec-Fetch-User 헤더가 웹 서버에 내비게이션 요청(이론적으로)은 사용자의 상호작용으로 인해 발생한다. 예를 들어 링크를 클릭하는 것이다.이 값은 항상 ?1입니다.브라우저가 사용자 활성화를 고려하지 않기 때문에 내비게이션이 발생하면 이 제목을 보내지 않습니다.

    브라우저 지원


    이 문서를 작성할 때 Chrome, Edge, Opera는 메타데이터 헤더를 지원합니다.그러나 걱정하지 마십시오. 당신은 완전히 뒤로 호환되는 방식으로 전략을 실시할 수 있습니다.최신 상태 here을 확인할 수 있습니다.

    격리 정책을 실시하다


    fetch 메타데이터 헤더가 이렇게 뛰어난 이유는 우리가 이렇게 할 수 있기 때문이다.

    클라이언트 상하문을 바탕으로 서버에서 요청을 막는 것은 우리가 이전에 보지 못했던 능력이다.그러나 이제 우리는 그것을 사용하고 격리 전략을 실현하도록 했다.
    격리 정책을 만들려면 HTTP 요청 헤더를 기반으로 요청을 막을 수 있는 필터, 중간부품 등이 필요합니다.
    나는 NodeJS를 예로 들겠지만, 어떤 개발 프레임워크에서도 이런 중간부품은 통상적으로 실현되기 어렵다.
    우리는 이 골격부터 시작할 것이다.
    app.use(function (req, res, next) {})
    

    1. 이전 버전과의 호환성


    우선, 메타데이터 헤더를 가져오는 요청이 전혀 없도록 허용합니다.그렇지 않으면 메타데이터를 가져오는 것을 지원하지 않는 브라우저를 사용하는 사용자는 사이트를 방문할 수 없습니다.
    if (!req.headers['sec-fetch-site']) {
      return next()
    }
    if (!req.headers['sec-fetch-mode']) {
      return next()
    }
    if (!req.headers['sec-fetch-dest']) {
      return next()
    }
    

    2. 동일한 소스에서 모든 요청 허용


    프로그램이 정상적으로 작동하도록 하려면 같은 원본에서 온 모든 상호작용을 허용하십시오.
    if (req.headers['sec-fetch-site'] === 'same-origin') {
      return next()
    }
    

    3. 다른 사이트에서 요청하지 않는 것을 허용한다


    때때로 요청은 사용자가 책갈피를 열거나 URL 표시줄에 입력한 내용에서 비롯됩니다.이러한 상황에서 Sec-Fetch-Site의 값은 none이기 때문에 우리는 이렇게 하는 것을 허락한다.
    if (req.headers['sec-fetch-site'] === 'none') {
      return next()
    }
    

    4. 탐색 허용


    다른 사이트를 페이지에 연결하려면 내비게이션을 허용해야 합니다.그러나 내비게이션만 허용하고 사이트를 뛰어넘어 요청, 프레임워크, 그리고 우리가 꼭 원하지 않는 다른 것들도 허용한다.
    보안을 위해 HTTP 메서드가 GET이고 자원 목표가 document인지 확인하십시오.
    if (
      req.method === 'GET' &&
      req.headers['sec-fetch-mode'] === 'navigate' &&
      req.headers['sec-fetch-dest'] === 'document'
    ) {
      return next()
    }
    

    5. 다른 요청 차단


    지금까지 요청이 규칙에 맞지 않으면 거부하십시오.
    return res.status(403).json({
      error: 'Request blocked by the isolation policy.',
    })
    

    6.필요시 정책 완화


    원본이나 사이트를 뛰어넘는 상호작용을 허용하기를 원할 수도 있습니다.

    하위 도메인 허용


    자신의 하위 도메인에서 요청을 허용하려면 Sec-Fetch-Site 값이 same-site인 요청이 통과되는 것을 허용하십시오.
    if (req.headers['sec-fetch-site'] === 'same-site') {
      return next()
    }
    

    허용 프레임


    다른 사이트가 iframe에 당신의 페이지를 불러올 수 있도록 하려면, 목표가 GET일 때 iframe 요청을 내비게이션할 수 있도록 허락해 주십시오.
    if (
      req.method === 'GET' &&
      req.headers['sec-fetch-mode'] === 'navigate' &&
      req.headers['sec-fetch-dest'] === 'iframe'
    ) {
      return next()
    }
    

    7. 정책 테스트


    우리는 현재 상당히 엄격한 격리 정책을 실시했다.다음은 전체 내용입니다. (예시에서 iFrame 또는 하위 필드를 사용할 수 없습니다.)너는 포크 코드 here을 사용할 수 있다.
    app.use(function (req, res, next) {
      // If fetch metadata is not supported, allow the request.
      if (!req.headers['sec-fetch-site']) {
        return next()
      }
      if (!req.headers['sec-fetch-mode']) {
        return next()
      }
      if (!req.headers['sec-fetch-dest']) {
        return next()
      }
    
      // If the request originates from your own web application, allow it.
      if (req.headers['sec-fetch-site'] === 'same-origin') {
        return next()
      }
    
      // If the request doesn't originate from a website at all (bookmark, etc.) then allow it.
      if (req.headers['sec-fetch-site'] === 'none') {
        return next()
      }
    
      // If the request is a navigation GET request, allow it.
      if (
        req.method === 'GET' &&
        req.headers['sec-fetch-mode'] === 'navigate' &&
        req.headers['sec-fetch-dest'] === 'document'
      ) {
        return next()
      }
    
      // If no rules matched, block the request.
      return res.status(403).json({
        error: 'Request blocked by the isolation policy.',
      })
    })
    
    나는 작은 테스트 페이지 here을 만들었다.이것은 이미지를 불러오고 HTML 폼을 발표하며 보호된 웹 사이트를 구축하려고 시도합니다.만약 네가 사이트를 열면, 너는 이 세 개 모두 실패할 것이라는 것을 발견할 것이다.

    링크가 하나 더 있습니다.링크를 클릭하면 페이지가 정확하게 불러옵니다.

    또한 Firefox나 Safari에서 페이지를 불러올 수도 있기 때문에 뒤로 호환성이 제한된 것 같습니다.

    8. 배치 전략


    생산 환경에 정책을 처음 배치할 때 로그만 기록하는 방법을 사용하는 것이 좋습니다.
    정책은 변하지 않지만, 요청을 막는 것이 아니라, X로 인해 요청이 막히는 것을 기록하고, 요청을 통과시킨다.
    이렇게 하면 강제 정책을 최종적으로 배치하기 전에, 정책이 어떤 내용을 파괴할 수 있는지, 그리고 어떤 내용을 추가해야 하는지 곧 알게 될 것입니다.

    결론


    메타데이터 헤더를 가져오는 것은 개발자가 이전에 불가능했던 방식으로 웹 응용 프로그램을 보호할 수 있도록 하는 현저한 브라우저 기능이다.
    효과적인 전략을 실현하는 것은 매우 간단하여, 예를 들어 하위 영역의 구조나 상호작용을 허용하는 모든 특수한 수요를 쉽게 만족시킬 수 있다.
    생산 환경에 정책을 배치할 때 로그만 기록하는 방법부터 시작하는 것이 좋습니다.그리고 강제 정책이 아무것도 파괴하지 않을 것이라고 확신할 때 그것을 배치합니다.
    브라우저에 따라 브라우저 지원이 부족하거나 시험 단계에 있지만, 제목은 뒤로 호환되는 방식으로 사용할 수 있습니다.

    네트워크 보안 리스트 전자 표 가져오기!



    ☝️ Subscribe에서 AppSec Monkey까지의 이메일 목록은 우리의 가장 좋은 내용을 당신의 우편함에 직접 보내고 2021 웹 응용 프로그램 보안 목록 전자 표를 무료로 받아서 환영 선물로 드립니다!

    여기 멈추지 마.


    만약 당신이 이 글을 좋아한다면, AppSec Monkey의 다른 응용 프로그램 보안 안내서도 볼 수 있습니다.
    읽어주셔서 감사합니다.

    좋은 웹페이지 즐겨찾기