-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcontent_protector.js
More file actions
130 lines (117 loc) · 4.05 KB
/
Copy pathcontent_protector.js
File metadata and controls
130 lines (117 loc) · 4.05 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
// content_protector.js
// Page-context wrapper for camera/mic (getUserMedia) and geolocation.
// Talks to SecureWeb via window.postMessage -> content.js -> background.js.
(function () {
const ORIGIN = window.location.origin;
// ---- Generic bridge: ask extension for permission ----
function securePermissionCheck(kind) {
return new Promise((resolve) => {
// If postMessage unavailable (very unlikely), fail CLOSED (block)
if (!window.postMessage) {
resolve(false);
return;
}
const requestId = "sw-perm-" + Date.now() + "-" + Math.random().toString(16).slice(2);
function onMessage(event) {
if (!event || !event.data) return;
const data = event.data;
if (
data &&
data.source === "SecureWebExtension" &&
data.type === "permissionResponse" &&
data.requestId === requestId
) {
window.removeEventListener("message", onMessage);
resolve(!!data.allowed);
}
}
window.addEventListener("message", onMessage);
// Ask content.js, which will talk to background.decidePermission
window.postMessage(
{
source: "SecureWeb",
type: "permissionCheck",
requestId,
kind,
origin: ORIGIN
},
"*"
);
// Safety timeout: if extension doesn't respond in time, FAIL CLOSED (block)
setTimeout(() => {
window.removeEventListener("message", onMessage);
resolve(false);
}, 800); // 0.8s
});
}
// ---- Wrap getUserMedia (camera/mic) ----
try {
if (navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === "function") {
const originalGetUserMedia = navigator.mediaDevices.getUserMedia.bind(
navigator.mediaDevices
);
navigator.mediaDevices.getUserMedia = function (constraints) {
const kind = "camera-mic";
return securePermissionCheck(kind).then((allowed) => {
if (!allowed) {
// Denied by SecureWeb
const err = new DOMException(
"Camera/Microphone access blocked by SecureWeb",
"NotAllowedError"
);
return Promise.reject(err);
}
// Allowed -> call original browser API
return originalGetUserMedia(constraints);
});
};
}
} catch (e) {
// fail silently
}
// ---- Wrap geolocation (getCurrentPosition / watchPosition) ----
try {
if (navigator.geolocation) {
const originalGeo = navigator.geolocation;
const originalGetCurrentPosition = originalGeo.getCurrentPosition.bind(originalGeo);
const originalWatchPosition = originalGeo.watchPosition.bind(originalGeo);
navigator.geolocation.getCurrentPosition = function (success, error, options) {
const kind = "geolocation";
securePermissionCheck(kind).then((allowed) => {
if (!allowed) {
if (typeof error === "function") {
error(
new DOMException(
"Location access blocked by SecureWeb",
"NotAllowedError"
)
);
}
return;
}
originalGetCurrentPosition(success, error, options);
});
};
navigator.geolocation.watchPosition = function (success, error, options) {
const kind = "geolocation";
return securePermissionCheck(kind).then((allowed) => {
if (!allowed) {
if (typeof error === "function") {
error(
new DOMException(
"Location access blocked by SecureWeb",
"NotAllowedError"
)
);
}
// Return dummy id so app won't crash
return -1;
}
return originalWatchPosition(success, error, options);
});
};
}
} catch (e) {
// fail silently
}
})();