서드파티 스크립트 및 SRI 감사

페이지가 불러오는 모든 서드파티 스크립트는 페이지의 전체 권한으로 실행됩니다 — DOM을 읽을 수 있고, 양식 입력을 지켜볼 수 있으며, 방문자의 세션 안에서 행동할 수 있습니다. 이 감사는 페이지의 정적 HTML을 가져와 참조하는 모든 외부 스크립트를 나열하고, 어떤 것이 서드파티인지, 어떤 것이 Subresource Integrity(SRI) 해시를 가졌는지, 어떤 것이 정확한 버전에 고정되었는지를 표시합니다 — 그리고 무결성이 부족한 서드파티 스크립트에 대해서는 태그에 바로 붙여넣을 수 있도록 sha384 해시를 계산합니다.

마지막 업데이트:

사이트의 벤더 스크립트가 바뀌거나 중단될까 걱정되나요? myeventwatch로 무료 모니터링 — 만료 및 다운타임 알림, 카드 불필요.

이 감사가 확인하는 것 — 그리고 볼 수 없는 것

체커는 페이지를 한 번 가져와 제공받은 HTML — 정적 HTML만 — 을 파싱합니다. 그 마크업 안의 모든 <script src>는 호스트와 함께 나열되고, 호스트가 페이지의 등록 가능 도메인과 일치하면 퍼스트파티로, 그렇지 않으면 서드파티로 분류되며, 브라우저가 당신을 보호할 수 있는지를 결정하는 두 속성, 즉 integrity(브라우저가 파일 실행 전에 검증하는 SRI 해시)와 crossorigin(교차 출처 SRI 검사가 작동하는 데 필요한 속성)을 확인합니다. URL 안의 버전도 평가됩니다: [email protected]이나 /v2.4/로 주소가 지정된 스크립트는 고정된 것이고, latest나 버전이 없는 주소는 아무도 당신의 사이트를 건드리지 않아도 언제든 내용이 바뀔 수 있는 움직이는 표적입니다.

경계를 분명히 하세요. 중요하기 때문입니다: v1은 페이지의 정적 HTML만 파싱합니다 — JavaScript가 런타임에 주입하는 스크립트는 포함되지 않습니다. 태그 관리자, 동의 도구, 채팅 위젯은 페이지가 로드된 뒤 코드에서 script 요소를 만드는 일이 흔하며, 정적 파싱은 그것들을 결코 보지 못합니다. 이 감사를 템플릿과 CMS가 직접 참조하는 것들의 목록 — 보통 문제에서 가장 크고 가장 고치기 쉬운 부분 — 으로 취급하고, 태그 관리자 컨테이너는 관리자 자체의 미리보기와 변경 이력에서 따로 감사하세요. 인라인 스크립트(src가 없는 블록)는 SRI를 전혀 가질 수 없으므로 결과에 사실로 셉니다. 동반 가이드가 그것들을 어떻게 다룰지 설명합니다.

해시 열: 계산된 것이지, 결코 추측이 아닙니다

integrity 속성이 부족한 서드파티 스크립트에 대해서는, 체커가 스크립트 자체를 가져옵니다 — 이 사이트의 모든 체커와 같은 SSRF 방어 가져오기 경로를 통해, 해당 스크립트 중 처음 15개, 각각 512 KB까지 — 그리고 그 SHA-384 해시를 계산합니다. 가져오기가 성공하면 SRI 셀에는 전체 스니펫 integrity="sha384-…"가 표시되어 crossorigin="anonymous"와 나란히 태그에 붙여넣을 준비가 됩니다. 해시는 스크립트가 실제로 가져와졌을 때만 표시됩니다. 가져오기가 실패했거나, 파일이 너무 컸거나, 스크립트가 15개 상한을 넘어섰다면, 셀에는 대신 그 메모가 표시됩니다 — 자리 표시자나 추측값은 결코 표시되지 않습니다 — 그리고 해결책은 정확한 파일이 손에 있는 당신 자신의 빌드 파이프라인에서 해시를 생성하는 것입니다.

관련 검사: 보안 헤더 검사는 응답 헤더를 채점합니다 — SRI의 자연스러운 파트너인 Content-Security-Policy를 포함합니다 —, SSL 채점기는 그 스크립트들이 도착하는 전송 경로를 다루고, 동반 글 서드파티 스크립트는 공급망 리스크입니다는 실제 사건, SRI가 막는 것과 막지 못하는 것, 반복 가능한 감사 루틴을 살펴봅니다.

판정은 이렇게 읽어야 합니다: 무결성이 있고 버전이 고정된 서드파티 스크립트가 건강한 경우입니다 — 브라우저는 교체되거나 편집된 파일을 거부할 것입니다. 무결성이 없는 서드파티 스크립트는 자동으로 악성인 것은 아닙니다. 보호되지 않는다는 뜻으로, 그 내용은 호스트가 오늘 제공하는 것이 무엇이든 그것이며, 변경에 대한 유일한 경고는 피해 그 자체가 될 것입니다. 고정되지 않은 주소는 부족한 해시와 같은 의심을 받아야 합니다. latest URL 위의 SRI 해시는 벤더가 첫 업데이트를 배포하는 순간 깨지기 때문입니다 — 그래서 두 발견은 나란히 보고되고, 그래서 오래가는 해결책은 항상 쌍입니다: 먼저 정확한 버전을 고정하고, 그 다음 바로 그 파일의 해시를 구하세요.

이 페이지가 보여 주는 사실

서드파티호스트의 등록 가능 도메인이 페이지의 것과 다른 스크립트 — 다른 사람이 제공하고 당신의 페이지 권한으로 실행되는 코드.
무결성(SRI)태그가 integrity 속성을 가졌는지 여부: 브라우저가 파일 실행 전에 대조하는 암호화 해시로, 조금이라도 다르면 실행을 거부합니다.
Crossorigin태그가 교차 출처 SRI 검사에 필요한 crossorigin 속성을 가졌는지 여부. 없으면 브라우저는 로드에 SRI를 적용할 수 없습니다.
고정됨URL이 정확한 버전([email protected], /v2.4/)을 이름으로 지정하는지, 내용이 조용히 바뀔 수 있는 떠다니는 latest나 버전 없는 주소가 아닌지.
계산된 SRI무결성이 부족한 서드파티 스크립트에 대해, 체커가 파일을 실제로 가져와 계산한 sha384 해시 — 가져오기 성공 시에만, 해당 스크립트 중 처음 15개에 표시됩니다.

자주 묻는 질문

이 감사는 내 페이지가 실행하는 모든 스크립트를 보나요?

아니요 — 그리고 페이지는 그 점을 분명히 밝힙니다: v1은 페이지의 정적 HTML만 파싱하므로, JavaScript가 런타임에 주입하는 스크립트는 포함되지 않습니다. 태그 관리자, A/B 테스트 도구, 동의 배너, 채팅 위젯은 보통 로드 후 스크립트를 주입합니다. 그것들은 태그 관리자에서나 브라우저의 네트워크 패널로 감사하세요. 이 감사가 완전히 다루는 것은 제공된 HTML이 직접 참조하는 모든 스크립트이며, 라이브러리, CDN 위젯, 모니터링 임베드가 사는 곳이 바로 거기입니다.

SRI 열의 해시는 어디에서 오나요?

체커가 스크립트 파일 자체를 가져와 그 SHA-384 해시를 계산합니다. 대상은 integrity 속성이 부족한 서드파티 스크립트로, 처음 15개, 각각 512 KB까지입니다. 해시는 스크립트가 실제로 가져와졌을 때만 표시됩니다: 가져오기가 실패했거나, 파일이 너무 컸거나, 상한에 도달했다면 셀에는 해시 대신 그 메모가 표시됩니다. 스니펫을 crossorigin="anonymous"와 함께 script 태그에 붙여넣고, 버전이 바뀔 때마다 감사를 다시 실행하세요 — 새 버전은 새 해시를 뜻합니다.

태그 관리자 스크립트는 고정 해시를 가질 수 없습니다. 그럼 어떻게 하나요?

맞습니다 — 태그 관리자 컨테이너는 바뀌도록 설계되었으므로 SRI로 고정할 수 없고, 목적 자체가 바뀌는 코드를 불러오는 스크립트도 마찬가지입니다. 그런 것들에 대한 통제는 다릅니다: 컨테이너에 게시할 수 있는 사람을 제한하고, 그 변경 이력을 코드 변경처럼 검토하고, 필요한 페이지에서만 불러오고, Content-Security-Policy를 사용해 주입된 스크립트가 할 수 있는 일과 데이터를 보낼 수 있는 곳을 제한하세요. SRI는 고정된 라이브러리를 보호하고, 거버넌스는 동적인 것들을 보호합니다.

integrity 속성이 없는 것은 긴급 상황인가요?

그것은 상존하는 노출이지 사건이 아닙니다. 그 스크립트는 거의 확실히 벤더가 오늘 제공하려는 파일입니다. 문제는 내일 — 벤더 침해, 계정 탈취, 도메인 만료 뒤에 — 다른 파일이 와도 아무것도 그것을 막거나 표시하지 않는다는 것입니다. 수정 순서: 로그인, 결제, 개인정보가 있는 페이지의 스크립트를 먼저, 다음으로 다른 모든 곳에서 고정되고 해시된 라이브러리를, 마지막으로 긴 꼬리를 다루세요. 버전이 고정되면 각 수정은 태그 한 줄 변경입니다.

고정 열은 왜 스크립트를 "latest"나 "버전 없음"이라고 부르나요?

고정 판정은 URL에 대한 휴리스틱한 읽기 입니다: @1.2.3이나 /v2.4/ 같은 버전처럼 보이는 세그먼트는 고정으로 셉니다. 명시적인 latest 세그먼트는 떠다니는 것으로, 어디에도 버전이 없는 URL은 버전 없음으로 셉니다. 휴리스틱이라고 표시하는 이유는 릴리스 체계를 아는 것은 벤더뿐이기 때문입니다 — 하지만 보안 요점은 표시명에 의존하지 않습니다: 그 URL의 바이트가 URL은 그대로인 채 바뀔 수 있다면, SRI 해시는 살아남을 수 없습니다. 그러니 먼저 고정하고, 그 다음 해시를 구하세요.