Access-Control-Allow-Private-Network
Access-Control-Allow-Private-Network 헤더는 웹 애플리케이션이 로컬 네트워크 리소스에 접근할 수 있도록 허용하기 위해 사용됨. 이는 특히 CORS(Cross-Origin Resource Sharing) 정책의 일부로, 로컬 네트워크 보호와 관련된 보안 강화를 위해 도입된 새로운 기능임
사용 배경
웹 애플리케이션은 보안상의 이유로 기본적으로 다른 출처(origin)에 있는 리소스에 접근할 수 없음. 로컬 네트워크의 민감한 데이터에 접근하는 것은 특히 더 제한되어야 함. 이 헤더는 웹 브라우저가 **프라이빗 네트워크(예: 로컬 서버, IoT 디바이스)**에 접근하는 요청을 처리할 수 있도록 허가하는 역할을 함
다음은 사고가 발생하는 대략적인 순서임
- 웹 애플리케이션 취약점 발견: 악성 웹사이트가 CORS 설정이 잘못된 로컬 네트워크 장치(예: 라우터, IoT 디바이스)에 접근.
- 민감한 데이터 탈취: 해당 디바이스로부터 비밀번호, 설정 정보 등 민감한 데이터를 무단으로 요청 및 수집.
- 리소스 악용: 네트워크 장치를 악의적으로 재설정하거나, 원격 코드 실행 등의 공격 발생.
- 피해: 내부 네트워크까지 침투해 데이터 유출 및 시스템 마비.
주변에서 볼 수 있는곳
그리드 프로그램(아프리카tv, 치지직 등)
하드웨어를 사용하는 프로그램(아두이노 웹 블록코딩)
작동 방식
최신 브라우저(Chrome, edge 등)은 하위 리소스의 비공개 네트워크 요청보다 먼저 CORS 프리플라이트 요청을 전송하여 대상 서버의 명시적 권한을 요청하기 시작합니다. 이 사전 비행 요청은 새 헤더 Access-Control-Request-Private-Network: true를 전송하며 이에 대한 응답은 상응하는 헤더 Access-Control-Allow-Private-Network: true를 전송해야 합니다. 목표는 비공개 네트워크의 라우터 및 기타 기기를 대상으로 하는 교차 사이트 요청 위조 (CSRF) 공격으로부터 사용자를 보호하는 것입니다. 이러한 공격으로 수십만 명의 사용자가 영향을 받았으며 공격자가 사용자를 악성 서버로 리디렉션할 수 있었습니다.
출처 : https://developer.chrome.com/blog/private-network-access-preflight?hl=ko#introduction
이걸 왜 만든거임
로컬 네트워크 엑세스를 완전히 없애지 않고 남겨둔건 몇가지 이유가 있음
- 로컬네트워크의 유용성
많은 웹 애플리케이션이 로컬 네트워크의 리소스와 통신해야하는 합법적인 요구가 있을 수 있음
예: 프린터, iot디바이스, 라우터 등 - 사용자 경험보장
웹에서 로컬 네트워크의 디바이스를 설정하는 경우가 있는데 그런 작업들이 불가능해질 수 있음
예: 프린터 설정 페이지가 동작하지 않음 - 보안과 접근의 균형
무조건 차단하면 보안은 강화되지만 실질적인 서비스는 불가능해지는 경우가 있음. 이 헤더는 안전한 요청만 허용할 수 있는 제어권을 서버와 브라우저에게 제공함 - 최소한의 신뢰 기반 통신
이 헤더는 비공개 네트워크 접근은 명시적 허가가 필요하다는 원칙을 적용함. 서버가 Access-Control-Allow-Private-Network: true 를 전송하지 않으면 접근이 차단됨
이거 왜 씀
웹에서 모바일 기기의 블루투스 비콘 스캔 기능을 사용해야했음
연결 기반 블루투스 기기들이 아닌 주로 위치기반으로 사용되는 비콘을 스캔해야 했음
웹 블루투스는 실험적 기능이라서 직접 활성화 시켜야하며 연결 기반만 작동하고 비콘 스캔은 지원하지 않음
가장 자주 사용되는 해결방법은 웹뷰를 포함하는 앱을 만들고 해당 앱에서 비콘을 스캔한 뒤 웹뷰로 넘겨주고 웹에서 받은 그 비콘 정보를 사용하는 방법임
그 방법은 그냥 재미 없을거 같아서 로컬 서버로 작동하는 비콘 스캔용 앱을 만듬
위 앱은 실행하면 간단한 상태를 출력하고 포그라운드에서 비콘을 스캔하며 로컬 api요청을 처리함
요약: 그냥 재밌을거 같아서
fastapi에서 설정 방법
fastapi에서 CORS미들웨어를 추가할 수 있음
Access-Control-Allow-Private-Network는 CORS프리플라이트 요청을 전송해서 명시적으로 권한을 요청함
위 두가지를 알고 있다면 다음과 같이 코드를 작성할 수 있음
베이스는 starlette의 CORS 미들웨어의 생성자를 사용했고 그냥 추가로 인자 하나 더 들어간거 말고는 차이가 없음
타입힌트를 신경쓰지 않는다면 더 간단하게도 작성가능
from typing import Optional, Sequence | |
from fastapi import FastAPI | |
from fastapi.middleware.cors import CORSMiddleware as _CORSMiddleware | |
from starlette.types import ASGIApp | |
class CORSMiddleware(_CORSMiddleware): | |
def __init__( | |
self, | |
app: ASGIApp, | |
allow_origins: Sequence[str] = (), | |
allow_methods: Sequence[str] = ("GET",), | |
allow_headers: Sequence[str] = (), | |
allow_credentials: bool = False, | |
allow_private_network: bool = False, | |
allow_origin_regex: Optional[str] = None, | |
expose_headers: Sequence[str] = (), | |
max_age: int = 600, | |
) -> None: | |
super().__init__( | |
app, | |
allow_origins, | |
allow_methods, | |
allow_headers, | |
allow_credentials, | |
allow_origin_regex, | |
expose_headers, | |
max_age, | |
) | |
if allow_private_network: | |
self.preflight_headers[ | |
"Access-Control-Allow-Private-Network" | |
] = "true" |
추가 정보가 필요하다면 starlette의 구현을 CORS 미들웨어를 살펴보면됨


진짜 특별한 구현이 필요하다면 ASGI를 준수하는 미들웨어를 직접 구현해도 가능
다운로드
Access-Control-Allow-Private-Network 를 처리하는 비콘 스캔 로컬 서버 앱 다운로드 링크(안드로이드)
https://boa9448.tistory.com/45
끝
'날먹을 위한 몸부림 > 쉽지않음' 카테고리의 다른 글
보러가기 쉽지 않음 - django rest framework 시리얼라이저의 data 속성 (1) | 2024.12.25 |
---|