Grammarly 확장의 배신
(dbushell.com)Grammarly 확장 프로그램이 웹사이트를 깨뜨린 이유
- 최근 몇 달 동안 웹사이트 레이아웃이 이상하게 깨졌다는 보고를 종종 받았음
- 문제의 원인은 Grammarly 브라우저 확장 프로그램으로 밝혀졌고, 이를 확인하기 위해 본인도 직접 설치해봄
문제 발견 과정
- Grammarly 확장 프로그램은 다음과 같은 권한을 요청함:
- 모든 웹사이트의 데이터 접근
- 알림 표시
- 브라우저 탭 접근
- Firefox에서 실험한 결과, Grammarly는 웹페이지에 자체 스타일시트를 삽입함
- 이 스타일시트는 웹페이지에서 직접 탐지할 수 없음 (숨겨진 스타일시트)
- Content Security Policy까지 우회함
-
<html>
태그 안에<grammarly-desktop-integration>
요소도 삽입됨 (목적은 불분명)
왜 내 사이트였나?
- Grammarly의 스타일시트 끝에 다음 코드가 포함되어 있음:
:host, :root { --rem:16 }
- 이 설정은 기본 CSS 단위인 1rem = 16px와 겹치며, 저자도 --rem이라는 커스텀 프로퍼티를 사용 중이었음
- Grammarly는 고정된 --rem 값을 전역으로 설정하고, 동적 폰트 사이징을 시도함
- 이로 인해 저자의 유동적인 타이포그래피 계산이 깨짐
저자의 대응
- 처음에는 Mutation Observer를 이용해 Grammarly가 삽입한 요소를 감지하고 !important 스타일로 덮어씀
- 이후 자신의 CSS 변수명을 --rem에서 **--🤡 (유니코드 이모지)**로 변경함
- 이모지는 CSS 변수 이름으로 유효함
- 이렇게 하면 Grammarly의 전역 --rem 설정과 충돌을 피할 수 있음
문제의 본질
- Grammarly는 웹 확장 프로그램으로서 모든 웹사이트에 전역 스타일을 강제로 삽입함
- 특히 --rem처럼 일반적인 CSS 변수명을 사용하는 것은 매우 해로움
- 코드 내부에서는 무작위 클래스명을 쓰면서도, 왜 굳이 공용 네이밍을 전역으로 적용했는지 이해할 수 없음
- 실제 확장을 사용하지 않아도 코드가 삽입됨
결론 및 제안
- 저자는 Grammarly에 문의했으며, 빠른 응답은 있었지만 기술적으로 문제를 이해하는 담당자와 연결되지는 못함
- 이상적인 해결책은 Grammarly가 --🤡 같은 변수명을 사용하고, 나머지 개발자들이 자유롭게 --rem을 사용할 수 있도록 하는 것임
Hacker News 의견
-
내 확장 프로그램 문제는 조금 다름. 우리는 지리적 위치 테스트를 위해 프록시 서버 간 전환을 쉽게 하는 확장 프로그램을 배포함
- 몇 달 전 최악의 클라이언트 데모를 경험했음. 제품이 작동하지 않는 것처럼 보였음
- 많은 디버깅 끝에 1Password 확장 프로그램의 최근 업데이트가 우리의 것을 망가뜨렸음을 발견함
- 그들은 인증 이벤트를 구독하고 있었지만 반환하지 않았고, 이로 인해 우리의 구독자가 호출되지 않았음
- 1Password의 지원 팀은 Grammarly보다 나았지만, 우선순위를 설득하는 것은 어려움
- 정부 웹사이트에 필요한 러시아 확장 프로그램도 같은 문제가 있음
-
스크립트나 스타일을 알 수 없는 페이지에 주입할 때는 변수에 네임스페이스를 지정하는 것이 최소한의 예의임
-
많은 화면 공유와 녹화가 기본적으로 모든 웹사이트에 그린 침입을 포함하는 것을 보는 것은 무서움
- 시각적 방해뿐만 아니라 프라이버시와 공격 벡터가 문제임
- Chrome은 필요할 때만 확장을 활성화할 수 있음. 왜 아무도 이렇게 하지 않는지 궁금함
-
Grammarly Extension의 엔지니어임. dbushell.com의 UX를 망가뜨려 죄송함
- 의도한 것이 아니었고, 이를 방지하기 위해 다양한 기술을 사용 중임
- dbushell.com에 대한 예외를 임시로 추가했음
- 스타일 격리를 보장하기 위한 변경 작업 중임
-
이 문제를 엔지니어링 팀에 전달했음
-
Google Translate가 내 웹 앱을 망가뜨리는 비슷한 문제가 있음
- Google Translate를 사용하는 사용자가 앱이 망가졌다고 불평함
- Google이 앱의 상태를 더 높은 메타 레벨에서 변경했기 때문임
- Google Translate를 감지하고 경고를 출력하려고 함
-
작업 중 브라우저 확장 프로그램과 관련된 많은 sentry 오류가 있음
- Chrome의 Google Translate는 React 기반 사이트를 망가뜨리는 것으로 악명 높음
- 새로운 확장 문제를 무시하는 번거로운 작업이 필요함
- 클라이언트 측 필터링을 사용하여 수집량을 줄임
-
웹을 가장 망가뜨릴 수 있는 변수가 무엇일지 궁금함
- --primary-color: transparent
-
적대적인 브라우저 확장 프로그램을 어떻게 처리하는지 궁금함
-
이 방법을 사용하여 플러그인을 하이재킹할 수 있는지 궁금함
- 최소한 텍스트를 주입할 수 있어야 하며, 사용자의 신뢰를 악용하여 로그인 폼을 렌더링할 수도 있음
- 다른 사람이 제어하는 문서에 요소를 주입하는 것이 정말 안전한지 의문임