Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/extension/src/manifest.json
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue:
The extension was requesting the "management" permission by default, which gives access to all installed extensions and is highly sensitive.

Fix:
Moved "management" from required permissions to optional_permissions.

Impact:
Improves security by following the principle of least privilege and reducing unnecessary access.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem:
This extension makes API requests through fetch(), but there are no provisions for a timeout in case the server fails to respond. The API call will get hung forever, leaving the application in a loading mode or "Scanning..."

Solution:
Developed a utility method called fetchWithTimeout() that incorporates AbortController to enforce timeout for the API requests. All API fetch requests (e.g., fetchResults, triggerScan, pollScanStatus) were updated to use the fetchWithTimeout() method.

Consequences:
No more stuck applications due to hung API calls.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1EQJhE6eyAVdlLZ5lH0M+w1dcfVl3fOr4H1H2nw3aUksRoCwivfGOZNgGU1SrwdFeC7HlynvIn/w5YwKvCR+0EMsJAi7gp3yQj1NyegYf/d0EwBIHgJiGvrAn47zG/25GlrNdU4M+88B8kMquouPL6Sq5G99nYVkc6DNdE+8iIZe9aqQYIXFa7idAZ+qu44WUz4g+GfjketId+BkHYSN/RM7UY2iY8XEV/Zw5di1Jr0sGHQqZViTeN2wH+9/C5SeHTT3pIKAldCLkru++jFHc3YpAxcrxukkxh1R4a+H+FjpoqWYrfXVmiS8MMZoHZJcOJzEjDen6Wfq/YJKnxOYRwIDAQAB",
"manifest_version": 3,
"name": "Extension Shield",
"permissions": [ "management", "storage" ],
"permissions": ["storage"],
"optional_permissions": ["management"],
"update_url": "https://clients2.google.com/service/update2/crx",
"version": "1.1.0"
}
33 changes: 29 additions & 4 deletions packages/extension/src/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

var API = 'https://extensionshield.com';
var CACHE_TTL = 6 * 3600 * 1000;
function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);

return fetch(url, {
...options,
signal: controller.signal
}).finally(() => clearTimeout(id));
}
var WEBSTORE_URL_PREFIX = 'https://chromewebstore.google.com/detail/x/';
var SCAN_POLL_INTERVAL = 3000;
var SCAN_POLL_MAX = 60;
Expand Down Expand Up @@ -426,7 +435,7 @@

function fetchResults(extId) {
var url = API + '/api/scan/results/' + encodeURIComponent(extId);
return fetch(url).then(function (res) {
return fetchWithTimeout(url).then(function (res) {
if (res.status === 404) return { _st: 'not_found' };
if (!res.ok) return { _st: 'error' };
return res.json().then(function (j) { j._st = 'ok'; return j; });
Expand All @@ -435,7 +444,7 @@

function triggerScan(extId) {
var webstoreUrl = WEBSTORE_URL_PREFIX + encodeURIComponent(extId);
return fetch(API + '/api/scan/trigger', {
return fetchWithTimeout(API + '/api/scan/trigger', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: webstoreUrl })
Expand All @@ -446,7 +455,7 @@
}

function pollScanStatus(extId) {
return fetch(API + '/api/scan/status/' + encodeURIComponent(extId))
return fetchWithTimeout(API + '/api/scan/status/' + encodeURIComponent(extId))
.then(function (res) {
if (!res.ok) return { status: 'unknown' };
return res.json();
Expand Down Expand Up @@ -602,7 +611,23 @@
evHtml = '<div class="evidence-cell"><span class="finding-count" style="color:var(--high)">—</span></div>';
}

tr.innerHTML = '<td>' + extHtml + '</td><td style="text-align:center">' + pillHtml + '</td><td>' + evHtml + '</td>';


const td1 = document.createElement('td');
td1.textContent = extHtml;

const td2 = document.createElement('td');
td2.style.textAlign = "center";
td2.textContent = pillHtml;

const td3 = document.createElement('td');
td3.textContent = evHtml;

tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);


rows.appendChild(tr);
}

Expand Down
Loading