-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground.js
More file actions
171 lines (143 loc) · 4.24 KB
/
background.js
File metadata and controls
171 lines (143 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Background Service Worker
// 배지 아이콘 색상 설정
const BADGE_COLORS = {
high: '#DC2626', // 🔴 Red - 고위험
medium: '#FBBF24', // 🟡 Yellow - 중위험
low: '#10B981', // 🟢 Green - 저위험
none: '#9CA3AF' // ⚪ Gray - 위험 없음
};
const BADGE_TEXT = {
high: '!',
medium: '?',
low: '✓',
none: ''
};
// 설치 시 초기화
chrome.runtime.onInstalled.addListener(() => {
console.log('React2Shell Scanner 설치됨');
// 초기 스토리지 설정
chrome.storage.local.set({
scanHistory: [],
settings: {
autoScan: true,
showNotifications: true
}
});
});
// Content script로부터 메시지 수신
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === 'SCAN_COMPLETE') {
handleScanComplete(request.data, sender.tab);
sendResponse({ status: 'received' });
}
if (request.type === 'SCAN_ERROR') {
handleScanError(request.data, sender.tab);
sendResponse({ status: 'error_received' });
}
return true;
});
// 스캔 완료 처리
async function handleScanComplete(scanData, tab) {
if (!tab || !tab.id) return;
const riskLevel = scanData.riskLevel;
// 배지 업데이트
await updateBadge(tab.id, riskLevel);
// 스캔 기록 저장
await saveScanHistory(scanData);
// 고위험인 경우 알림 (설정에 따라)
const settings = await chrome.storage.local.get('settings');
if (settings.settings?.showNotifications && riskLevel === 'high') {
showNotification(scanData);
}
console.log(`[${tab.id}] 스캔 완료:`, scanData);
}
// 스캔 오류 처리
async function handleScanError(errorData, tab) {
if (!tab || !tab.id) return;
console.error(`[${tab.id}] 스캔 오류:`, errorData);
// 오류 발생 시 회색 배지
await updateBadge(tab.id, 'none');
}
// 배지 업데이트
async function updateBadge(tabId, riskLevel) {
try {
await chrome.action.setBadgeBackgroundColor({
color: BADGE_COLORS[riskLevel] || BADGE_COLORS.none,
tabId: tabId
});
await chrome.action.setBadgeText({
text: BADGE_TEXT[riskLevel] || '',
tabId: tabId
});
// 아이콘 변경
const iconPath = getIconPath(riskLevel);
await chrome.action.setIcon({
path: iconPath,
tabId: tabId
});
} catch (error) {
console.error('배지 업데이트 오류:', error);
}
}
// 위험도별 아이콘 경로 반환
function getIconPath(riskLevel) {
const color = {
high: 'red',
medium: 'yellow',
low: 'green',
none: 'gray'
}[riskLevel] || 'gray';
return {
16: `icons/icon-${color}-16.png`,
48: `icons/icon-${color}-48.png`,
128: `icons/icon-${color}-128.png`
};
}
// 스캔 기록 저장
async function saveScanHistory(scanData) {
try {
const result = await chrome.storage.local.get('scanHistory');
let history = result.scanHistory || [];
// 최근 100개만 유지
history.unshift(scanData);
if (history.length > 100) {
history = history.slice(0, 100);
}
await chrome.storage.local.set({ scanHistory: history });
} catch (error) {
console.error('기록 저장 오류:', error);
}
}
// 알림 표시
function showNotification(scanData) {
chrome.notifications.create({
type: 'basic',
iconUrl: 'icons/icon-red-128.png',
title: 'React2Shell 취약점 감지',
message: `${scanData.hostname}에서 RSC 사용이 감지되었습니다. 취약점 위험이 있을 수 있습니다.`,
priority: 2
});
}
// 탭 업데이트 시 배지 초기화
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'loading') {
// 로딩 중일 때 배지 초기화
updateBadge(tabId, 'none');
}
});
// 탭 활성화 시 해당 탭의 스캔 결과 복원
chrome.tabs.onActivated.addListener(async (activeInfo) => {
try {
const tab = await chrome.tabs.get(activeInfo.tabId);
if (tab.url) {
const hostname = new URL(tab.url).hostname;
const result = await chrome.storage.local.get(`scan_${hostname}`);
const scanData = result[`scan_${hostname}`];
if (scanData) {
await updateBadge(activeInfo.tabId, scanData.riskLevel);
}
}
} catch (error) {
// URL이 없는 경우 (chrome:// 페이지 등) 무시
}
});