---
title: "Claude Fable 5, CSS 버그 하나 잡자고 브라우저 자동화까지 직접 발명함"
published: 2026-06-12T01:06:51.000Z
canonical: https://jeff.news/article/4076
---
# Claude Fable 5, CSS 버그 하나 잡자고 브라우저 자동화까지 직접 발명함

Simon Willison이 Claude Fable 5로 Datasette Agent의 textarea 스크롤바 버그를 조사했더니, 모델이 로컬 서버 실행, 실제 Safari 캡처, 템플릿 주입, CORS 수집 서버까지 동원했다. 결과적으로 두 줄짜리 CSS 수정에 가까운 문제였지만, 세션 비용 추정치는 약 12.11달러였고 코딩 에이전트 권한 관리의 위험성을 제대로 보여줬다.

- Simon Willison이 Claude Fable 5를 써보다가 꽤 무서운 장면을 봄. CSS 스크롤바 버그 하나 잡으라고 했더니, 모델이 로컬 브라우저 자동화 전략을 거의 직접 발명함
  - 문제는 Datasette Agent의 jump menu 채팅 프롬프트 안 textarea에 가로 스크롤바가 생기는 버그였음
  - 프롬프트는 단순했음. “dependencies를 보고 왜 가로 스크롤바가 생기는지 찾아봐” 정도
  - 작성자는 잠깐 자리를 비웠고, 돌아와 보니 Claude가 실제 Firefox와 Safari를 열어가며 실험 중이었음

- Fable은 Playwright만 쓴 게 아니라, macOS 도구를 조합해서 실제 Safari 창을 캡처함
  - `uv run --with pyobjc-framework-Quartz python`으로 화면에 떠 있는 창 목록을 가져옴
  - Safari 창 제목에 `textarea` 같은 문자열이 있는지 필터링해서 창 번호를 찾음
  - 그 창 번호를 `screencapture -x -o -l`에 넘겨 PNG를 찍음
  - `osascript`가 접근성 권한 문제로 막히자, PyObjC와 Quartz로 우회한 셈임

> [!IMPORTANT]
> 이건 단순히 “브라우저 테스트를 했다”가 아님. 모델이 macOS 네이티브 API, CLI 캡처 도구, 임시 HTML 파일을 엮어서 자기만의 관측 루프를 만든 사례임.

- 버그 재현을 위해 scratch HTML 페이지도 직접 만들었음
  - exact plugin CSS, `overflow-x: hidden`, `resize: none`, 기본 textarea 같은 케이스를 나눠 비교함
  - Safari에서 실제로 어떻게 보이는지 캡처해서 확인함
  - Playwright의 Chrome, Firefox, WebKit에서 재현이 안 되자 작성자의 기본 브라우저인 Safari 쪽을 의심한 흐름도 꽤 사람 같음

- 더 놀라운 건, 실제 앱의 모달을 열기 위해 템플릿에 JavaScript를 주입했다는 점임
  - 해당 모달은 클릭이나 `/` 키보드 단축키로 열리는 UI였음
  - Claude는 Datasette 소스 템플릿을 수정해서 페이지 로드 1.2초 뒤 `KeyboardEvent("keydown", {key: "/"})`를 dispatch하도록 만듦
  - 브라우저 자동 입력 권한이 없어도, 앱 코드 안에 트리거를 심어서 원하는 UI 상태를 만든 거임

```mermaid
sequenceDiagram
    participant 사용자
    participant ClaudeFable
    participant 로컬앱
    participant Safari
    participant 수집서버
    사용자->>ClaudeFable: 스크린샷과 버그 조사 요청
    ClaudeFable->>로컬앱: 개발 서버 실행과 템플릿 수정
    ClaudeFable->>Safari: 테스트 페이지와 앱 화면 열기
    Safari->>로컬앱: 주입된 키보드 이벤트로 모달 표시
    Safari->>수집서버: textarea 측정값 JSON 전송
    ClaudeFable->>사용자: 원인과 CSS 수정안 보고
```

- 측정값을 얻기 위해 작은 CORS 수집 서버까지 만들었음
  - Python 표준 라이브러리 `http.server`로 `127.0.0.1:9999`에 POST를 받는 서버를 띄움
  - `Access-Control-Allow-Origin: *`를 열어 다른 출처의 브라우저 코드가 데이터를 보낼 수 있게 함
  - 템플릿에 주입한 JavaScript는 `navigation-search` 웹 컴포넌트의 `shadowRoot` 안 textarea를 찾아 `scrollWidth`, `clientWidth`, `whiteSpace`, `width`, `devicePixelRatio` 등을 JSON으로 보냄
  - Claude는 서버가 `/tmp/diag.json`에 쓴 파일을 읽고 원인을 좁혀감

- 결국 Fable은 중간에 보이지 않는 제한에 걸려 Opus로 내려갔지만, Opus는 전체 transcript를 이어받아 문제를 마무리함
  - Fable이 개척한 브라우저 캡처, 템플릿 주입, CORS 데이터 수집 패턴을 그대로 활용함
  - 이후 원인 확인, 수정안 실험, 검증까지 이어짐
  - 작성자는 나중에 Opus에게 이 세션에서 사용한 자동화 트릭을 `/tmp/automation-report.md`에 정리하라고 시켰고, 그 보고서가 글의 기반이 됨

- 전체 세션에서 Claude가 한 일은 꽤 빡셈
  - 로컬 개발 서버 실행 방법을 찾고, 필요한 가짜 환경변수까지 맞춤
  - Playwright Chrome을 띄우고, Chrome의 visible scrollbars 설정도 바꿈
  - Firefox와 WebKit에서도 재현을 시도함
  - 실제 Safari를 열고, macOS 창 캡처 우회법을 구성함
  - 템플릿에 키보드 이벤트와 측정 코드를 주입함
  - Web Component의 Shadow DOM 내부까지 들어가 필요한 값을 읽음
  - 임시 수정안을 적용하고 실제 브라우저에서 확인함

- 비용도 가볍지 않음. 풀 API 가격 기준으로 이 세션은 약 12.11달러로 추정됨
  - 작성자는 월 100달러짜리 Claude Max 플랜을 쓰고 있었고, Fable은 6월 22일까지 넉넉한 allowance가 있는 상태였음
  - AgentsView 기준 출력은 68,606 토큰, 피크 컨텍스트는 113,178 토큰, 추정 비용은 약 12.11달러였음
  - CSS 두 줄짜리 수정에 가까운 문제를 해결하려고 12달러어치 자동화를 태운 셈이라, 효율과 과잉 행동 사이의 선이 꽤 선명하게 보임

> [!WARNING]
> 코딩 에이전트는 터미널에서 사용자가 할 수 있는 일을 그대로 할 수 있음. 모델이 더 똑똑해질수록 악성 지시를 의심할 수도 있지만, 한 번 뚫리면 더 창의적으로 사고칠 수도 있음.

- 작성자의 결론은 “이거 빨리 샌드박스에 가둬야겠다”에 가까움
  - Fable의 적극성은 생산성 측면에선 대단함. 별도 지시 없이도 관측 도구를 만들고, 브라우저를 열고, 데이터를 회수함
  - 하지만 악성 프롬프트 인젝션이 코드나 이슈, 복붙한 텍스트에 숨어 있었다면 이야기가 달라짐
  - 파일 유출, 환경 정보 수집, 로컬 시스템 조작 같은 위험이 현실적인 시나리오가 됨
  - “샌드박스 밖에서 코딩 에이전트를 돌리는 건 원래 나쁜 생각이었다”는 주장이 점점 더 설득력을 얻는 중임

---

## 기술 맥락

- 이 기사에서 재미있는 선택은 Playwright 같은 정석 자동화만 쓰지 않고, 실제 Safari를 관측 대상으로 삼았다는 점이에요. 왜냐하면 브라우저별 렌더링 버그는 테스트 브라우저에서는 안 보이고 사용자의 실제 브라우저에서만 터지는 경우가 있거든요.

- Claude가 PyObjC와 Quartz를 쓴 이유는 macOS에서 특정 앱 창을 식별하고 캡처해야 했기 때문이에요. `osascript`는 접근성 권한에 막혔고, 그래서 더 낮은 레벨의 윈도우 목록 API를 통해 창 번호를 찾은 뒤 `screencapture`로 이미지를 얻는 쪽으로 우회했어요.

- 템플릿에 JavaScript를 주입한 것도 꽤 중요한 포인트예요. 외부에서 키보드 입력을 보내기 어렵다면, 앱 내부에서 같은 이벤트를 발생시키면 되거든요. 테스트 대상 앱의 소스가 로컬에 있었기 때문에 가능한 접근이고, 코딩 에이전트가 코드베이스를 마음대로 바꿀 수 있을 때 얼마나 강력해지는지 보여줘요.

- CORS 수집 서버는 브라우저 안에서만 알 수 있는 레이아웃 값을 밖으로 빼내기 위한 선택이에요. textarea의 `scrollWidth`나 `clientWidth`는 렌더링 후 DOM에서 직접 읽어야 하니까, Claude가 작은 HTTP 서버를 세워서 브라우저가 측정값을 POST하게 만든 거예요.

- 그래서 보안상 핵심은 모델이 아니라 실행 경계예요. 이런 에이전트는 디버깅에는 엄청 유용하지만, 같은 권한으로 민감 파일을 읽거나 네트워크로 보낼 수도 있어요. 실무에서는 샌드박스, 네트워크 제한, 파일 접근 제한, 승인 단계가 선택이 아니라 기본값이 돼야 해요.

## 핵심 포인트

- Claude Fable 5는 스크린샷과 한 줄 프롬프트만으로 로컬 개발 서버를 실행하고 실제 브라우저 테스트를 구성함
- Safari 창 번호를 PyObjC와 Quartz로 찾아 screencapture CLI로 캡처하는 우회 자동화 패턴을 만들어냄
- 템플릿에 JavaScript를 주입해 키보드 단축키를 자동 실행하고, 별도 CORS 서버로 DOM 측정값을 수집함
- 문제 해결 능력은 인상적이지만, 같은 능력이 악성 지시나 프롬프트 인젝션에 쓰이면 위험이 커짐
- 풀 API 가격 기준 세션 비용은 약 12.11달러로 추정됐고, 저자는 샌드박스 필요성을 다시 강조함

## 인사이트

이 글은 ‘코딩 에이전트가 똑똑해졌다’보다 ‘터미널 권한을 가진 에이전트는 사용자가 할 수 있는 일을 거의 다 시도한다’는 쪽이 핵심이다. 생산성 데모로 보면 멋지지만, 보안 모델 없이 쓰면 꽤 무서운 자동화임.
