Files
chzzk-bypass/content.js
chzzk-bypass owner 15a852c8ad v1.2.1: HTTP 헤더(User-Agent / sec-ch-ua*)도 Mac 으로 위장
v1.2.0 까지는 navigator.* JS 값만 Mac 으로 덮어쓰고 실제 HTTP 요청 헤더는
원본(Windows)으로 나가서, 치지직 핑거프린팅이 클라이언트 사이드 불일치를
잡아내 "허용되지 않는 비정상적 접근" 팝업을 띄우는 것으로 추정됨.

declarativeNetRequest modifyHeaders 규칙으로 다음 요청 헤더를 Mac 값으로
덮어써 JS 레벨 (navigator.*) 과 네트워크 레벨이 일치하도록 한다:

- User-Agent
- sec-ch-ua
- sec-ch-ua-platform
- sec-ch-ua-mobile

부수 변경:
- host_permissions 에 *.pstatic.net 추가 (치지직 비디오/이미지 CDN)
- README / content.js 주석에 두-레이어 위장 구조 명시
2026-05-28 18:27:31 +09:00

90 lines
2.9 KiB
JavaScript

// 치지직이 윈도우에서 1080p 시청 시 그리드 설치를 요구하는 것을 우회하기 위해
// navigator 의 OS/브라우저 식별 값들을 Mac 으로 위장한다.
//
// 이 파일은 JS 레벨 (navigator.*) 만 다룬다. 실제 HTTP 요청 헤더
// (User-Agent / sec-ch-ua / sec-ch-ua-platform / sec-ch-ua-mobile) 는
// rules.json 의 declarativeNetRequest modifyHeaders 규칙이 똑같이 Mac 으로
// 덮어쓴다. JS 와 네트워크 레벨 값이 어긋나면 치지직 핑거프린팅이
// "비정상 접근" 으로 보고 팝업을 띄우므로 두 레이어가 반드시 같은 값을
// 가져야 한다.
//
// userAgentData 의 getHighEntropyValues 까지 구현해 두지 않으면
// 치지직이 로드하는 nlog.js (네이버 핑거프린팅 / 로깅) 가
// `e.getHighEntropyValues is not a function` 으로 Uncaught TypeError 를 던지고,
// 그 자체가 비정상 접근 시그널이 될 수 있다. 그래서 객체 형태와 메서드까지
// 일관된 Mac 값으로 채워 둔다. (manifest 의 world: MAIN + run_at: document_start
// 덕분에 페이지 스크립트보다 먼저 적용된다.)
Object.defineProperty(navigator, 'userAgent', {
get: function () {
return 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36';
}
});
Object.defineProperty(navigator, 'platform', {
get: function () {
return 'MacIntel';
}
});
const __chzzkBypassBrands = [
{ brand: 'Chromium', version: '122' },
{ brand: 'Google Chrome', version: '122' },
{ brand: 'Not-A.Brand', version: '24' }
];
const __chzzkBypassFullVersionList = [
{ brand: 'Chromium', version: '122.0.0.0' },
{ brand: 'Google Chrome', version: '122.0.0.0' },
{ brand: 'Not-A.Brand', version: '24.0.0.0' }
];
const __chzzkBypassHighEntropy = {
brands: __chzzkBypassBrands,
mobile: false,
platform: 'macOS',
platformVersion: '10.15.7',
architecture: 'x86',
bitness: '64',
model: '',
uaFullVersion: '122.0.0.0',
fullVersionList: __chzzkBypassFullVersionList,
wow64: false,
formFactors: []
};
const __chzzkBypassUAData = {
brands: __chzzkBypassBrands,
mobile: false,
platform: 'macOS',
getHighEntropyValues: function (hints) {
// 항상 brands / mobile / platform 은 포함하고, 요청된 hints 만 추가로 채운다.
const out = {
brands: __chzzkBypassBrands,
mobile: false,
platform: 'macOS'
};
if (Array.isArray(hints)) {
for (const h of hints) {
if (Object.prototype.hasOwnProperty.call(__chzzkBypassHighEntropy, h)) {
out[h] = __chzzkBypassHighEntropy[h];
}
}
}
return Promise.resolve(out);
},
toJSON: function () {
return {
brands: __chzzkBypassBrands,
mobile: false,
platform: 'macOS'
};
}
};
Object.defineProperty(navigator, 'userAgentData', {
get: function () {
return __chzzkBypassUAData;
}
});