하위 리소스 무결성 이해
게시 됨: 2022-03-10 JavaScript 라이브러리의 CDN 호스팅 버전을 사용한 적이 있다면 스크립트 태그에서 이상하게 보이는 integrity
속성을 발견했을 것입니다. 이 속성에는 끝없는 영숫자 쓰레기가 포함되어 있어 더 깔끔한 코드를 찾기 위해 제거하고 싶을 수 있습니다.
이 모든 정크는 실제로 특정 유형의 해킹 및 손상으로부터 사이트를 보호하는 데 도움이 되는 SRI(Subresource Integrity)라는 정말 유용한 보안 기능입니다. 이 기사에서는 SRI가 무엇인지, 어떻게 사용자를 보호할 수 있는지, CDN에서 호스팅되는 파일뿐만 아니라 자체 프로젝트에서 SRI를 사용하는 방법을 살펴보겠습니다.
약간의 역사
JavaScript가 HTML 및 CSS에 비해 훨씬 열등한 사촌이었던 시절에는 스크립트가 웹 사이트의 공격 벡터로 사용될 수 있는 방법에 대해 너무 많이 생각할 필요가 없었습니다. 대부분의 사이트는 모두 자체 호스팅 인프라의 어딘가에 있는 단일 물리적 서버에서 호스팅되었으며 보안 모범 사례와 관련하여 우리가 방어하려고 생각한 서버였습니다.
브라우저의 기능이 향상되고 네트워크 연결이 더 두꺼워지면서 우리는 점점 더 많은 JavaScript를 사용하기 시작했고 결국 재사용 가능한 JavaScript 라이브러리가 등장하기 시작했습니다. 초기에 script.aculo.us, Prototype 및 jQuery와 같은 라이브러리는 페이지에 더 많은 상호 작용을 추가하려는 개발자들 사이에서 채택되기 시작했습니다.
이러한 추가된 라이브러리와 후속 플러그인으로 페이지 무게가 추가되었고 오래지 않아 우리는 프런트 엔드 성능에 대해 진지하게 생각하기 시작했습니다. 이전에 거대 기업의 전유물이었던 CDN(Content Delivery Networks)과 같은 리소스는 평범한 사람들이 멋진 웹사이트를 구축하는 데 보편화되었습니다.
그 과정에서 일부 밝은 스파크는 사이트가 모두 최신 jQuery와 같은 공통 라이브러리의 자체 복사본을 요청하고 모든 사이트에서 사용할 수 있는 라이브러리의 공통 CDN 버전이 있는 경우 사용자가 ' 같은 파일을 계속 다운로드해야 합니다. 그들은 파일을 사용하는 첫 번째 사이트에 대해 적중을 하겠지만, 그 후에는 로컬 브라우저 캐시에 저장되고 각 후속 사이트에 대해 다운로드를 건너뛸 수 있습니다. 천재!
이것이 jsdelivr.com
과 같은 URL을 사용하여 즐겨찾는 라이브러리에 대한 CDN 링크를 볼 수 있는 이유입니다. 사용자가 성능 이점을 볼 수 있도록 파일을 호스팅하기 위해 공통 CDN을 사용하고 있습니다.
무엇이 잘못될 수 있습니까?
이것은 여전히 훌륭하고 실용적인 작업 방법이지만 잠재적인 공격 벡터가 발생합니다. 지금이 2012년이고 모두가 새로운 jQuery 1.8을 사용하고 있다고 상상해 봅시다. 일을 하는 전통적인 방식으로 돌아가면 모든 사람이 자신의 서버에서 자신의 웹 사이트의 일부로 호스팅되는 자신의 jQuery 1.8 파일을 갖게 됩니다.
jQuery 기반 Hamburglar와 같은 일종의 사악한 행위자가 자신의 사악한 이익을 위해 라이브러리를 해킹하는 교활한 방법을 알아냈다면 모든 웹사이트를 개별적으로 대상으로 지정하고 서버를 손상시켜야 합니다. 어떤 영향. 많은 노력이 필요합니다.
그러나 모두가 공통 CDN에서 로드된 jQuery를 사용하고 있기 때문에 상황은 그렇지 않습니다. 그리고 내가 모두라고 말할 때 수백 개의 웹 페이지를 의미하는 것이 아닙니다. 수백만 개의 웹 페이지를 의미합니다. 갑자기 그 파일 하나가 우리의 그늘진 해커에게 매우 매력적인 표적이 되었습니다. 한 파일을 손상시킬 수 있다면 전 세계 수백만 개의 웹 페이지에서 매우 빠르게 코드를 실행할 수 있습니다.
그 코드가 무엇인지는 중요하지 않습니다. 페이지를 훼손하는 장난일 수도 있고, 비밀번호를 훔치는 코드일 수도 있고, 암호화폐를 채굴하는 코드일 수도 있고, 웹에서 당신을 팔로우하고 마케팅 프로필을 만드는 교활한 추적자일 수도 있습니다. 중요한 것은 개발자가 페이지에 추가한 무고한 파일이 변경되었고 이제 사이트의 일부로 실행 중인 악의적인 JavaScript가 있다는 것입니다. 그것은 큰 문제입니다.
하위 리소스 무결성 입력
SRI는 시계를 되돌리고 코드를 사용하는 유용한 방법을 포기하는 대신 위에 간단한 수준의 보안을 추가하는 솔루션입니다. SRI와 integrity
속성이 하는 일은 페이지에 링크한 파일이 절대 변경되지 않도록 하는 것입니다. 그리고 변경되면 브라우저는 이를 거부합니다.
코드가 변경되지 않았는지 확인하는 것은 컴퓨터 과학에서 아주 오래된 문제이며 고맙게도 잘 확립된 솔루션이 있습니다. SRI는 가장 간단한 파일 해싱을 잘 채택하고 있습니다.
파일 해싱은 파일을 가져와서 해시 또는 체크섬이라고 하는 짧은 문자열 표현으로 줄이는 알고리즘을 통해 파일을 실행하는 프로세스입니다. 잡초에 빠지지 않고 프로세스는 반복 가능하거나 되돌릴 수 있으므로 해시와 함께 파일을 다른 사람에게 제공하면 동일한 알고리즘을 실행하여 두 항목이 일치하는지 확인할 수 있습니다. 파일이 변경되거나 해시가 변경되면 더 이상 일치하는 항목이 없으며 뭔가 잘못되었음을 알고 파일을 신뢰해야 합니다.
SRI를 사용할 때 웹 페이지는 해시를 보유하고 서버(CDN 또는 모든 위치)는 파일을 보유합니다. 브라우저는 파일을 다운로드한 다음 integrity
속성의 해시와 일치하는지 빠르게 계산합니다. 일치하면 파일을 사용하고 일치하지 않으면 차단합니다.
그것을 밖으로 시도
Bootstrap 버전에 대한 CDN 링크를 얻기 위해 오늘 getbootstrap.com
으로 이동하면 다음과 같은 태그가 제공됩니다.
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
src
속성이 우리에게 익숙한 것과 같으며 integrity
속성이 현재 해시로 알고 있는 것을 보유하고 있음을 알 수 있습니다.
해시는 실제로 두 부분으로 나뉩니다. 첫 번째는 사용할 해싱 알고리즘을 선언하는 접두사입니다. 이 경우 sha384
입니다. 그 다음에는 대시가 오고 그 다음에는 base64
로 인코딩된 해시 자체가 옵니다.
이미지와 같은 인라인 파일을 페이지로 인코딩하는 방법으로 base64
에 익숙할 수 있습니다. 이것은 암호화 프로세스가 아닙니다. ASCII로 깔끔하게 변환되는 방식으로 잠재적으로 지저분할 수 있는 데이터를 인코딩하는 빠르고 편리한 방법일 뿐입니다. 이것이 웹에서 많이 사용되는 이유입니다.
이것을 보면 브라우저는 bootstrap.min.js
를 다운로드합니다. 실행하기 전에 해시를 base64
로 디코딩한 다음 sha384
해시 알고리즘을 사용하여 해시가 방금 다운로드한 파일과 일치하는지 확인합니다. 일치하면 파일이 실행됩니다.
해당 태그를 페이지에 넣은 다음 브라우저 도구의 네트워크 탭으로 이동하여 파일이 로드되었는지 확인하여 이를 테스트할 수 있습니다.
bootstrap.min.js
(및 필요한 jQuery 파일)가 성공적으로 로드되었음을 알 수 있습니다.
내가 잘못된 것으로 알고 있는 해시를 업데이트하면 어떻게 되는지 봅시다.
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-SmashingMagazineIsCoolForCats" crossorigin="anonymous"></script>
보시다시피 내 페이지에 지정된 해시가 더 이상 파일과 일치하지 않아 파일이 차단됩니다.
자신의 프로젝트에서 SRI 사용하기
CDN의 라이브러리에 대해 이 기능을 사용하는 것은 훌륭하며 integrity
속성이 있는 포함된 파일을 사용하는 옵션이 표시되면 해당 옵션을 확실히 선호해야 합니다. 그러나 CDN의 대규모 프로젝트에 국한되지 않고 자신의 사이트에 직접 사용할 수 있습니다.
해커가 사이트에 있는 몇 개의 파일에만 액세스할 수 있는 시나리오를 상상하는 것은 전혀 무리가 아닙니다. 내 생각에 우리 중 대부분은 WordPress 사이트가 거기에 있는지조차 몰랐던 불쾌한 쓰레기로 인해 손상된 클라이언트, 동료 또는 친구를 본 적이 있다고 생각합니다.
SRI는 이것으로부터도 당신을 보호할 수 있습니다. 자신의 파일에 대해 무결성 해시를 생성하면 원격으로 호스팅되는 파일과 마찬가지로 사이트에서 변경 사항을 거부하도록 할 수 있습니다.
해시 생성
예상대로 컴퓨터 터미널에서 몇 가지 명령을 실행하여 파일에 대한 해시를 생성할 수 있습니다. 이를 수행하는 방법에 대한 이 예는 MDN 하위 리소스 무결성 페이지에서 제공됩니다.
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
그것은 FILENAME.js
의 내용을 가져오고 sha384
를 사용하여 다이제스트를 생성하기 위해 openssl
에 입력으로 전달한 다음 결과를 base64
로 인코딩하기 위해 다른 openssl
명령에 입력으로 전달됩니다. 복잡하고 모호할 뿐만 아니라 JavaScript 파일이 변경될 때마다 손으로 하고 싶은 일도 아닙니다.
더 유용하게는 이것을 사이트의 빌드 프로세스에 어떻게든 통합하기를 원할 것이며 상상할 수 있듯이 이미 만들어진 옵션이 많이 있습니다. 정확한 구현은 프로젝트에 따라 크게 다르지만 다음은 몇 가지 구성 요소입니다.
Gulp를 사용하여 사이트를 구축하는 경우 파일 및 해당 해시 목록이 포함된 JSON 파일을 출력하는 gulp-sri가 있습니다. 그런 다음 사이트에서 이를 사용할 수 있습니다. 예를 들어, 동적으로 렌더링된 사이트의 경우 템플릿 플러그인을 만들어 해당 파일을 읽고 필요한 경우 템플릿에 해시를 추가할 수 있습니다.
여전히 Gulp를 사용하고 있지만 정적 사이트(또는 정적으로 생성된 사이트)가 있는 경우 실제로 HTML 페이지를 통해 실행되고 필요한 곳에 해시를 추가하도록 페이지를 수정하는 gulp-sri-hash를 사용할 수 있습니다. 이는 매우 편리합니다.
Webpack을 사용하는 경우 실제 Webpack 스타일에서는 인간이 예상할 수 있는 것보다 더 복잡하지만 작동하는 것처럼 보이는 웹페이지 하위 리소스 무결성이 있습니다.
Handlebars 템플릿 엔진을 사용하는 경우 사용할 수 있는 옵션이 있는 것으로 보이며 빌드 프로세스가 기본 JavaScript인 경우 간단한 솔루션도 있습니다.
WordPress와 같은 CMS를 사용하는 경우 직접 시도하지는 않았지만 쉽게 만드는 플러그인을 찾았습니다. SRI 또는 하위 리소스 무결성을 사용하여 선택한 플랫폼에 대한 인터넷 검색은 올바른 방향을 가리킬 것입니다.
기본적으로 JavaScript 파일이 축소된 후 해시를 연결한 다음 시스템에서 <script>
태그를 출력하는 모든 부분에서 해당 해시를 사용할 수 있도록 하려고 합니다. 웹 플랫폼의 놀라운 점 중 하나는 기술적으로 매우 다양하지만 안타깝게도 좋은 구현 지침을 제공할 수 없다는 것입니다!
기타 주의 사항
이 기사에서 저는 JavaScript 파일에 대해 많은 이야기를 나눴습니다. JavaScript 파일이 해킹 공격으로부터 방어하는 것이 가장 합리적이기 때문입니다. SRI는 CSS와도 작동하므로 정확히 동일한 방식으로 사용할 수 있습니다. 악성 CSS의 위험은 훨씬 낮지만 사이트를 훼손할 가능성은 여전히 존재하며 CSS로 인해 CSS가 의도하지 않게 사이트를 해커에게 노출시킬 수 있는 브라우저 버그가 무엇인지 아는 사람이 있습니다. 그래서 거기에서도 SRI를 사용하는 작업입니다.
할 수 있는 또 다른 흥미로운 작업은 콘텐츠 보안 정책을 사용하여 페이지의 모든 스크립트(또는 스타일)가 SRI를 사용해야 하고 물론 SRI가 검증해야 함을 지정하는 것입니다.
Content-Security-Policy: require-sri-for script;
이것은 SRI가 항상 사용되도록 하는 방법이며, 작업 방법에 완전히 익숙해지거나 그렇지 않을 수 있는 여러 팀 구성원에서 작업하는 사이트에서 유용할 수 있습니다. 다시 말하지만, 이에 대해 더 읽을 수 있는 좋은 곳은 항상 훌륭한 하위 리소스 무결성에 대한 MDN 문서입니다.
마지막으로 이야기할 가치가 있는 것은 SRI에 대한 브라우저 지원입니다. 최신 브라우저의 지원은 Internet Explorer를 제외하고 광범위합니다. 그러나 사양이 이전 버전과 호환되는 방식으로 구현되었으므로 즉시 사용하는 것이 안전합니다. integrity
속성을 이해하는 브라우저는 해시를 사용하고 무결성을 검사하며 이전 브라우저는 항상 그랬던 것처럼 계속 작동하며 계속 작동합니다. 물론 이전 브라우저에서는 추가 보호 기능을 사용할 수 없지만 지원을 제공하는 브라우저에서는 사용할 수 있습니다.
결론
integrity
속성에 있는 이상한 해시가 무엇을 하는지 뿐만 아니라 웹사이트에 대한 특정 유형의 공격을 방어하기 위해 해시를 사용하는 방법도 보았습니다. 물론 모든 유형의 공격으로부터 사이트를 보호할 수 있는 단 하나의 총알은 없지만 하위 리소스 무결성은 체인에서 정말 유용한 도구입니다.
보안 결함을 악용하는 것은 종종 여러 개의 작은 조각을 정렬하는 것과 관련이 있습니다. A가 제자리에 있고 B가 발생하도록 할 수 있다면 C의 버그가 D를 가능하게 합니다. SRI와 같은 브라우저 기능은 사물을 조금 더 묶고 잠재적으로 해당 사슬을 끊고 해커가 원하는 것을 얻는 것을 방지할 수 있는 좋은 방법을 제공합니다. 게다가 빌드 프로세스나 CMS에 통합할 수 있다면 한 번 설정하고 잊어버릴 수 있어야 하고 일상적인 불편을 겪지 않을 것입니다.
따라서 Subresource Integrity를 진지하게 살펴보고 가능하면 사이트에 구현하는 것이 좋습니다.