Comoji가 키 입력을 어디에도 보내지 않는지 확인하는 방법
Comoji는 Mac의 모든 앱에 무료 Slack 스타일 :emoji: 자동 완성을 더해 줘요.
Comoji는 macOS에서 가장 깊이 파고드는 두 가지 권한인 손쉬운 사용과 입력 모니터링을 요청해요. 저희는 모든 것이 로컬에서 처리되고 입력한 내용은 절대 업로드되지 않는다고 말해요. Reddit의 한 사용자가 당연한 반론을 잘 짚어 줬어요. 저희 말을 대체로 믿긴 하지만, 그저 말 한마디만 믿고 그런 권한을 넘겨주는 건 여전히 찜찜하다는 거였죠.
타당한 반론이고, 그 답이 “저희를 더 믿어 주세요”여서는 안 돼요. 이 글이 그 방법 안내예요. 아래의 모든 명령은 읽기 전용이고, 5분 정도면 되며, Comoji가 네트워크에서 무엇을 하고 무엇을 하지 않는지 여러분의 컴퓨터에서 직접 확인할 수 있게 해 줘요. 연결하는 호스트 전체 목록을 포함한 참고용 버전은 보안 페이지에 있어요.
실제로 확인하는 것
키로거는 수집한 걸로 뭔가를 해야 해요. 어딘가로 보내거나, 어딘가에 기록하죠. 이건 검증하기에 작고 구체적인 주장이고, macOS에는 그걸 검증할 도구가 들어 있어요. 프로세스가 연 모든 네트워크 소켓을 나열하고, 보낸 모든 바이트를 세고, 배포된 바이너리에 박힌 호스트 이름을 읽고, 네트워크 접근을 완전히 막은 뒤 무엇이 고장 나는지 지켜볼 수 있어요.
여기에 Comoji 전용인 건 없어요. 이런 권한을 요청하는 어떤 Mac 앱에든, 저희 앱을 포함해 똑같은 단계를 쓰세요. 그게 핵심이에요.
시작하기 전에
Comoji를 실행해 두고 터미널을 여세요(Applications → Utilities → Terminal). 아래의 모든 명령은 읽기 전용 검사예요. 아무것도 설치하거나 바꾸거나 지우지 않아요. 개발 빌드를 설치했다면 프로세스 이름이 ComojiDev이니, Comoji가 나오는 곳마다 그걸로 바꿔 쓰세요.
먼저 실행 중인지 확인하고 프로세스 ID를 얻으세요:
pgrep -x Comoji숫자가 하나 나와야 해요. 아무것도 나오지 않으면 Comoji가 실행 중이 아닌 거예요(메뉴 막대 앱이니 Dock이 아니라 메뉴 막대를 확인하세요).
1단계: 입력하는 동안 네트워크 연결 지켜보기
lsof는 열린 파일을 나열하는데, Unix 시스템에서는 네트워크 소켓도 파일이에요. Comoji의 프로세스 ID로 범위를 좁히면 지금 앱이 열고 있는 모든 연결이 나와요:
lsof -nP -i -a -p "$(pgrep -x Comoji)"기대하는 결과는 아무 출력도 없는 것이에요. 빈 응답은 프로세스가 네트워크 연결을 하나도 갖고 있지 않다는 뜻이에요. 이제 입력해 보세요. 메시지를 열고 :fire, :tada, :liz 자동 완성을 몇 번 해 보고, 한두 문단 쓴 다음 명령을 다시 실행하세요. 여전히 비어 있어요.
한 번의 스냅숏은 이론상 확인 사이에 열렸다 닫힌 연결을 놓칠 수 있으니, 대신 계속 지켜보세요. 이걸 남는 터미널 윈도우에 붙여 넣고, Mac을 평소처럼 쓰는 동안 실행해 두세요:
while :; do
printf '%s ' "$(date +%T)"
lsof -nP -i -a -p "$(pgrep -x Comoji)" | tail -n +2 | awk '{print $9}' | paste -sd' ' -
echo
sleep 2
done아무리 많이 입력해도 2초마다 뒤에 아무것도 없는 타임스탬프만 찍혀요. 멈추려면 Control-C를 누르세요.
그다음, 루프가 돌아가는 동안 네트워크를 *써야 하는* 일을 해 보세요. 메시지에서 /gif를 입력하고 뭔가를 검색하는 거예요. 이제 타임스탬프 옆에 api.giphy.com과 giphy.com CDN 호스트가 나타나요. 이 대비가 이 테스트에서 유용한 부분이에요. 연결이 있었다면 루프가 보여 줬을 거라는 걸 증명하니까, 입력하는 동안 비어 있던 줄은 보이는 그대로의 의미예요.
2단계: 바이트 세기
nettop은 프로세스별 누적 트래픽을 추적하므로, 샘플링 방식의 확인으로는 놓칠 만큼 짧은 연결도 잡아내요:
nettop -P -p "$(pgrep -x Comoji)"열어 둔 채로 몇 분 동안 입력하되, /gif와 /sticker 선택기는 쓰지 마세요. bytes_in과 bytes_out 열은 0에 머물러요. 끝내려면 q를 누르세요.
3단계: 다운로드한 앱에서 호스트 이름 읽기
프로세스는 아는 곳에만 연결할 수 있고, 호스트 이름은 바이너리 안에 저장되어 있어야 해요. strings는 컴파일된 파일에서 읽을 수 있는 텍스트를 뽑아내니, 소스 코드 없이도 목록을 볼 수 있어요:
strings -a /Applications/Comoji.app/Contents/MacOS/Comoji \
| grep -Eo 'https?://[A-Za-z0-9._-]+' | sort -u
/usr/libexec/PlistBuddy -c 'Print :SUFeedURL' \
/Applications/Comoji.app/Contents/Info.plist나오는 건 Google의 스티커 아트워크 CDN(fonts.gstatic.com), Firebase Storage의 업데이트 피드(storage.googleapis.com), 그리고 앱에서 링크를 클릭할 때 브라우저에 넘겨지기만 하는 comoji.io와 다른 프로젝트 주소 몇 개예요.
정돈된 버전이 아니라 실제로 보이는 것과 맞도록 솔직한 단서 두 가지를 덧붙일게요. api.giphy.com은 전체 URL로 저장되지 않고 코드에서 호스트 이름으로 조립되기 때문에 첫 번째 목록에는 나오지 않아요. strings -a … | grep -Eo '[a-z0-9.-]*giphy\.com'으로 직접 검색하세요. 이 패턴은 호스트 이름만 잡기 때문에 번들에 함께 들어 있는 API 키는 출력하지 않아요. 그리고 번들에 포함된 Sparkle 업데이트 프레임워크는 Contents/Frameworks 안에 자체 문서 URL(sparkle-project.org, andymatuschak.org)을 갖고 있는데, 이건 Comoji가 연결하는 호스트가 아니라 서드파티 라이브러리 안의 문자열이에요.
4단계: 차단하고 무엇이 고장 나는지 보기
어떤 출력도 믿을 필요가 없으니 가장 강력한 테스트예요. 아웃바운드 방화벽을 설치하세요. LuLu는 무료 오픈 소스이고, Little Snitch는 오래된 상용 선택지예요. 모든 아웃바운드 연결에 알림을 띄우도록 설정한 다음, Comoji의 모든 연결을 영구적으로 거부하세요.
이모지 자동 완성은 처음부터 네트워크가 필요 없었기 때문에 아무 기한 없이 그대로 작동해요. 작동을 멈추는 건 업데이트 확인과, 아직 캐시하지 않은 스티커나 GIF 아트워크 다운로드뿐이에요. 로컬이라는 주장이 거짓이라면, 바로 여기서 요란하게 무너질 거예요.
5단계: 앱이 정말 저희 것인지 확인하기
위의 모든 건 디스크에 있는 사본을 검사한 거예요. 그 사본이 Apple이 공증한 바로 그것이고, 그 뒤로 아무도 수정하지 않았는지 확인해 둘 만해요:
codesign -dv --verbose=4 /Applications/Comoji.app
spctl -a -vvv -t exec /Applications/Comoji.app
codesign -d --entitlements - /Applications/Comoji.appcodesign은 앱에 서명한 Developer ID를 출력하고, spctl은 source=Notarized Developer ID와 함께 accepted라고 답해야 하며, 권한(entitlements) 덤프는 앱이 애초에 무엇을 할 수 있도록 허용되어 있는지 보여 줘요.
저희 쪽에서 하는 일
직접 해 볼 수 있는 검증은 약속보다 가치가 있지만, 약속도 어딘가에서 강제되어야 해요. 앱을 빌드할 때마다 두 가지가 실행돼요:
- Comoji가 연결할 수 있는 호스트의 전체 목록은 소스 코드 안의 선언이고, 네트워크 접점으로 공개되며 앱의 환경설정 → 개인정보 보호에도 표시돼요. 그 목록에 공개되지 않은 호스트에 앱이 접근할 수 있으면 자동 테스트가 빌드를 실패시켜요.
- 두 번째 테스트는 실제로 키 입력을 다루는 코드(이벤트 탭, 토큰 버퍼, 매처, 삽입기)를 검사해서, 거기에 네트워킹 API나 원격 URL이 하나라도 나타나면 빌드를 실패시켜요. Comoji에서 입력 내용을 보는 부분에는 네트워킹이 전혀 없고, 슬그머니 생길 수도 없어요.
같은 페이지에는 저희가 *하지 않기로* 결정한 것과 그 이유도 기록되어 있어요. 입력 경로의 오픈 소스화와 유료 제3자 검토 의뢰 같은 것들이요. 그래서 추측하는 대신 그 논리를 직접 따져 볼 수 있어요.
이 중 무엇이든 실행해 보고 저희가 공개한 내용과 어긋나는 걸 발견하면 support@comoji.io로 메일을 보내 주세요. 주장이 조용히 틀린 채로 남는 것보다는 페이지나 앱을 고치는 편이 나아요.
앱이 그 권한으로 실제로 무엇을 하는지는 기능 페이지에서 Comoji가 작동하는 모든 앱과 사이트와, 아예 실행되지 않았으면 하는 곳에서 조용히 있게 해 주는 앱별, 웹사이트별 비활성화 목록을 다뤄요.
자주 묻는 질문
Mac 앱이 내 키 입력을 어딘가로 보내고 있는지 어떻게 알 수 있나요?
터미널에서 lsof -nP -i -a -p "$(pgrep -x AppName)"을 실행하면 앱이 현재 열고 있는 네트워크 연결이 나오고, nettop -P -p "$(pgrep -x AppName)"을 실행하면 누적 송수신 바이트를 볼 수 있어요. 확실한 테스트를 원한다면 LuLu나 Little Snitch 같은 아웃바운드 방화벽을 설치해 앱을 완전히 차단한 뒤, 기능이 여전히 작동하는지 확인하세요.
Comoji는 제가 입력한 내용을 업로드하나요?
아니요. Comoji에는 계정, 원격 측정, 분석, 충돌 보고 도구가 없어요. 키 입력은 콜론으로 시작하는 단축키를 감지하기 위해서만 짧게 유지되는 메모리 버퍼에 담기고, 디스크에 기록되거나 전송되지 않아요. 앱이 연결하는 호스트는 정확히 네 곳이에요. 업데이트 피드, Google의 스티커 아트워크 CDN, 그리고 /gif 선택기를 쓸 때의 GIPHY API와 CDN이에요.
Comoji에 손쉬운 사용과 입력 모니터링 권한이 필요한 이유는 무엇인가요?
입력 모니터링은 :fire 같은 단축키를 입력하는 순간을 알아차리게 해 줘요. 손쉬운 사용은 포커스된 텍스트 필드와 캐럿 위치를 찾아 팝업을 올바른 자리에 띄우고, 이모지를 그 필드에 입력해 넣게 해 줘요. 어느 쪽도 텍스트 필드의 내용을 읽는 데 쓰이지 않으며, 보안 비밀번호 필드는 완전히 무시돼요.
Comoji는 오픈 소스인가요?
현재는 아니에요. comoji.io의 보안 페이지에 그 결정과 이유가 기록되어 있고, 네트워크 접점 전체가 공개되어 있으며, 다운로드한 공증된 바이너리로 로컬 처리 주장을 검증하는 단계별 명령도 안내되어 있어요.
Mac용 Comoji 무료 다운로드
Slack과 Discord 스타일 :emoji: 자동 완성을 Mac 어디서나. 무료.