← All reports

Local Network Access check lands in NetworkProcess

Component: WebKit NetworkProcess / Local Network Access | 944f82d

Local Network Access(LNA)는 기존 CORS-RFC1918 제안을 잇는 후속 규격입니다. 일반적인 공개 웹사이트처럼 상대적으로 public한 address space에서 시작된 요청이, private LAN이나 loopback처럼 덜 public한 address space에 도달하는 것을 제한합니다. 사용자가 권한을 허용한 경우에만 통과됩니다. 성격만 보면 mixed-content blocking이나 CORS에 가깝습니다. transport 계층에서 막는 방식이 아니라, load가 진행되기 전에 수행되는 비교에 해당합니다.

이번 commit은 WebKit 쪽 구현을 두 개의 새로운 WebCore 함수로 추가했습니다. localNetworkAccessPermissionRequestOutcome()과 performLocalNetworkAccessCheck()가 그것입니다. 그리고 이 둘을 NetworkResourceLoader에 연결했습니다. 그 결과 subresource response, redirect, cache hit이 모두 address space 비교를 거치고, 이어서 비동기 권한 판정을 받게 됩니다. 다만 아직 prompt UI는 존재하지 않습니다. NetworkSession::requestLocalNetworkAccessPermission()은 현재 동기적으로 결과를 반환하며, 실제로는 항상 Denied만 반환합니다. address space를 판별하지 못한 경우이거나, Prompt 결과에서 파생된 거부 처리 둘 중 하나입니다. grant store와 prompt를 띄울 수 없는 경로는 아직 도달할 방법 자체가 없기 때문입니다.

  NetworkResourceLoader
    ├─ response received ─┐
    ├─ redirect ──────────┼─► performLocalNetworkAccessCheck()
    └─ cache hit ─────────┘      ├─ compare client address space
                                 │    vs. target address space
                                 └─► localNetworkAccessPermissionRequestOutcome()
                                       └─ NetworkSession::requestLocalNetworkAccessPermission()
                                            (synchronous today; Denied in practice)

공개 웹 페이지가 사용자 모르게 로컬 네트워크 — router, IoT 기기, 개발 서버 — 에 접근하는 것을 차단하기 위해 새로 도입된 security boundary입니다. 적용 범위는 현재 subresource load에 한정됩니다. iframe navigation, main-resource load, permissions-policy 적용은 rollout 기간 동안 FIXME로 명시해 남겨두었습니다. 즉 경계 자체는 실제로 동작하지만, 아직 일부만 덮고 있는 상태입니다.

눈여겨볼 부분은 trust model입니다. 검사 자체는 NetworkProcess에서 수행됩니다. 다만 판정에 필요한 핵심 입력 두 가지 — client의 address space, 그리고 client가 secure context인지 여부 — 는 여전히 WebProcess가 보고한 값입니다. NetworkProcess가 독립적으로 산출하지 않습니다. policy container 상속이 아직 완전히 구현되지 않았기 때문입니다. 원래 NetworkProcess는 security에 직접 관여하지 않는 데이터에 한해서만 WebProcess를 부분적으로 신뢰합니다. 그런데 지금 구조에서는 security gate의 입력이 renderer에서 넘어옵니다. 임시 조치라는 점은 알려져 있지만, security 측면에서 의미가 있는 신뢰 결정에 해당합니다. 이 부분은 후속 bug로 따로 추적되고 있습니다.

Narrow: 아직 performLocalNetworkAccessCheck()를 거치지 않는 load 경로를 나열해 보는 방향입니다. iframe navigation과 main-resource load가 여기에 해당합니다. rollout 기간 동안에는 이 경로들이 local network 대상에 도달할 수 있는 정식 통로로 남아 있기 때문입니다. 판별 단서는 새 검사를 호출하지 않는 NetworkResourceLoader 진입 지점입니다. Wider: 다른 곳에도 옮겨 적용할 수 있는 패턴은, 권한이 높은 프로세스가 sandbox 프로세스에서 받은 값을 근거로 security 판단을 내리는 구조입니다. NetworkProcess가 renderer에서 보고한 출처 정보(address space, secure-context flag, origin 주장)를 단순 로깅이 아니라 차단 판정에 사용하는 지점이라면 동일한 질문이 성립합니다. 나머지 NetworkSession의 permission·policy hook도 renderer에서 온 입력을 쓰는지 점검할 필요가 있습니다. 검토 단서는 NetworkResourceLoadParameters 형태의 struct로 전달되어, header가 아니라 분기 조건으로 들어가는 필드입니다. Widest: 판정 함수가 stub 상태인 채로 도입된 security check는, 실제 동작이 한 번도 검증되지 않은 경계입니다. 그래서 더 넓게는 고정된 결과를 동기적으로 반환하는 permission API 전반이 탐색 대상이 됩니다. 이후 grant store를 실제로 사용하는 비동기 버전은 지금 테스트된 것과 전혀 다른 re-entrancy·lifetime 조건에서 동작하게 되기 때문입니다.