본문 바로가기
C.W.K.
Stream
Lesson 04 of 04 · published

권한은 줄이되 인증은 그대로

~13 min · firelink, read-only-lock, device-scoped, path-traversal

Level 0식은 재
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"할 수 있는 걸 줄이는 거랑, 이게 누군지 덜 확인하는 건 전혀 다른 얘기야."

런처는 힘이 작지, 덜 믿기는 게 아냐

family PIN 이 통과되면 Native Launcher 는 기기 단위 읽기 전용 자격을 받아. catalog 를 읽을 수 있고, 쓸 수 있는 건 딱 하나야. 자기 기기의 최근 목록이랑 즐겨찾기. 바꾸는 API 는 하나도 못 부르고, 그 쓰기가 repository 나 서비스, 다른 사람 설정에 닿지도 않아. 이게 깔끔하게 권한만 줄인 모양이야. 런처는 PIN 을 거쳤으니 인증은 완전히 된 상태고, 다만 아주 작고 무해한 자리로 범위가 좁혀졌을 뿐이지. 신원은 확실하고, 힘은 작고.

읽기 전용 잠금은 인증이랑 다른 축이야

같은 생각이 여행에도 안전한 둘러보기 모드를 줘. 읽기 전용 잠금을 켜면 그 세션에선 바꾸는 게 전부 꺼져. 호텔에서 그냥 상태만 보고 싶을 때나, 누구한테 구경만 시켜줄 때 좋지. 그러면서 인증은 조금도 안 약해져. 잠금은 세션이 뭘 할 수 있는지를 낮추지, 그 세션이 누구인지를 얼마나 확신하는지는 안 건드려. 이건 서로 다른 두 손잡이인데 뭉쳐놓는 실수가 흔해. '읽기 전용' 이 '덜 인증됨' 으로 구현되면 안 돼. 완전히 확인된 상태로 동시에 일부러 무력할 수 있어야 하고.

비밀이랑 파일은 제자리에

마무리로 위생 규칙 둘. 첫째, 비밀은 API 응답에도, 감사 기록에도, 로그에도, 런처 캐시에도 안 들어가. 자격이든 비밀이 섞인 명령 출력이든 세션 토큰이든. 아예 안 돌아다니는 비밀은 오가는 중에도, 기기에 남은 채로도 샐 수가 없거든. 둘째, 정적 파일은 정해둔 빌드 폴더에서만 내보내고, 없는 경로 요청엔 앱 껍데기를 돌려줘. 아무 파일이나 찾아 주는 게 아니라. 그래야 조작된 경로가 빌드 폴더를 걸어 나가서 보면 안 될 걸 못 읽어. 둘 다 같은 감각이야. 위험한 건 제 자리에 가둬둔다는 것.

'뭘 할 수 있나' 랑 '이게 누군지 얼마나 확실한가' 를 따로 놀게 해. 권한은 얼마든지 줄이되, 그걸 인증을 낮추는 걸로 꾸미지 마. 읽기 전용이면서 인증은 완전한 세션은 안전해. 근데 '읽기만 하니까 확인도 대충' 인 세션은 공격자가 네 대신 기꺼이 골라줄 지름길이야.

Code

힘은 줄이고 신원은 그대로, 비밀은 안 돌아다니고·typescript
type LauncherCredential = {
  deviceId: string;
  authenticated: true;          // went through the family PIN — fully verified
  scope: "read-only-catalog";   // reads the catalog...
  mayWrite: ["own-recents", "own-favorites"];  // ...writes ONLY its own device state
  // No mutation endpoint. Never touches repos, services, or others' prefs.
};

type WebSession = {
  authenticated: true;          // auth strength is a SEPARATE dial...
  readOnlyLock: boolean;        // ...from this capability dial (travel/sightseeing)
};
// read-only lock disables mutations WITHOUT weakening authentication.

// Hygiene, always: secrets/tokens/secret-bearing output NEVER appear in
//   API responses | audit detail | logs | launcher cache.
// Static served only from the declared build root; SPA fallback = app shell,
//   never an arbitrary filesystem path.

External links

Exercise

네가 아는 시스템의 '읽기 전용 모드' 나 '손님 화면' 을 찾아봐. 인증은 그대로 두고 권한만 줄인 거야, 아니면 '읽기 전용' 이 슬쩍 '덜 로그인됨' 을 뜻해? 후자라면 공격자가 어느 쪽을 고르고 싶어할지 적어봐. 그리고 따로, 정적 파일이나 다운로드 처리하는 자리를 봐. 조작한 경로로 의도한 폴더 밖을 읽을 수 있어?
Hint
위험한 패턴은 '어차피 아무것도 못 하니까' 인증 단계를 건너뛰는 읽기 전용 세션이야. 인증은 똑같이 두고 쓰기 권한만 빼. 파일 쪽은 늘 같은 고침이고. 경로를 풀어보고 허용된 폴더 안에 아직 있는지 확인한 다음에 내보내는 거.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.