@browsertotal/scanner 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -9
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,20 @@
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
## Why BrowserTotal Scanner?
|
|
18
|
+
|
|
19
|
+
**Real Browser Analysis** - Unlike static analysis tools, BrowserTotal Scanner launches a **real browser instance** to analyze URLs and extensions exactly as they would execute in a user's environment. This catches threats that only activate in actual browser contexts.
|
|
20
|
+
|
|
21
|
+
**Dynamic Behavior Tracing** - Every network request, DOM manipulation, cookie access, and API call is traced and recorded. See what extensions and websites actually *do*, not just what their code looks like.
|
|
22
|
+
|
|
23
|
+
**Sandboxed Execution** - All analysis runs in an isolated, sandboxed browser environment. Test suspicious URLs and extensions safely without risking your system.
|
|
24
|
+
|
|
25
|
+
**AI-Powered Threat Detection** - Combines runtime behavior analysis with LLM-powered code review to identify obfuscated malware, data exfiltration, and sophisticated supply chain attacks.
|
|
26
|
+
|
|
27
|
+
**Multi-Platform Coverage** - Scan browser extensions (Chrome, Firefox, Edge, Safari, Opera, Brave), IDE plugins (VS Code, JetBrains), and packages (npm, PyPI, WordPress) - all through a unified API.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
17
31
|
This package uses Puppeteer to automate browser interactions with BrowserTotal's analysis tools. It leverages a custom event system (`#automationEvent=true`) to receive complete scan results including AI/LLM analysis.
|
|
18
32
|
|
|
19
33
|
## Supported Platforms
|
|
@@ -228,15 +242,6 @@ const scanner = new BrowserTotalScanner({
|
|
|
228
242
|
});
|
|
229
243
|
```
|
|
230
244
|
|
|
231
|
-
### Authentication
|
|
232
|
-
|
|
233
|
-
The scanner uses a Proof of Work challenge-response system that works automatically in headless browsers. No API key is required - the computational proof of work prevents abuse while allowing automated access.
|
|
234
|
-
|
|
235
|
-
The scanner will automatically:
|
|
236
|
-
1. Request a challenge from the server
|
|
237
|
-
2. Solve the Proof of Work challenge
|
|
238
|
-
3. Submit analysis results with the solution for verification
|
|
239
|
-
|
|
240
245
|
## How It Works
|
|
241
246
|
|
|
242
247
|
The scanner uses a special automation mode that:
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var S=require('puppeteer');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var S__default=/*#__PURE__*/_interopDefault(S);var h=Object.defineProperty;var
|
|
1
|
+
'use strict';var S=require('puppeteer');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var S__default=/*#__PURE__*/_interopDefault(S);var h=Object.defineProperty;var y=(r,s)=>()=>(r&&(s=r(r=0)),s);var P=(r,s)=>{for(var t in s)h(r,t,{get:s[t],enumerable:true});};var l={};P(l,{BrowserTotalScanner:()=>exports.BrowserTotalScanner});function v(r){return Array.from(r).map(s=>s.charCodeAt(0).toString(16).padStart(2,"0")).join("")}var o,d,w;exports.BrowserTotalScanner=void 0;var c=y(()=>{o=process.env.BROWSERTOTAL_URL||"https://browsertotal.com",d=42e4,w={chrome:"google",firefox:"mozilla",edge:"microsoft",opera:"opera",safari:"safari",brave:"brave"};exports.BrowserTotalScanner=class{options;browser=null;constructor(s={}){this.options={headless:s.headless??true,timeout:s.timeout??d,waitForResults:s.waitForResults??true,disableAI:s.disableAI??true,userDataDir:s.userDataDir};}buildHashParams(){let s=["automationEvent=true"];return this.options.disableAI&&s.push("disableAI=true"),"#"+s.join("&")}async ensureBrowser(){return this.browser||(this.browser=await S__default.default.launch({headless:this.options.headless,args:["--no-sandbox","--disable-setuid-sandbox"],userDataDir:this.options.userDataDir})),this.browser}reportProgress(s,t){s&&s(t);}async scanUrl(s,t){let a=await(await this.ensureBrowser()).newPage();try{this.reportProgress(t,{phase:"initializing",message:"Starting URL scan..."});let n=v(s),i=`${o}/analysis/urls/${n}${this.buildHashParams()}`;this.reportProgress(t,{phase:"navigating",message:`Navigating to ${i}`});let p=this.waitForScanResultEvent(a,"url");if(await a.goto(i,{waitUntil:"networkidle2",timeout:this.options.timeout}),this.reportProgress(t,{phase:"scanning",message:"Waiting for scan results..."}),this.options.waitForResults){let u=await p;if(u)return this.reportProgress(t,{phase:"complete",message:"Scan complete"}),this.mapUrlEventResult(u,s,i)}throw this.reportProgress(t,{phase:"complete",message:"Scan error"}),new Error("Scan error")}finally{await a.close();}}async scanExtension(s,t="chrome",e){let a=w[t]||t,n=`${o}/analysis/live/store/${a}/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,n,`${t} extension`,e)}async scanVSCodeExtension(s,t){let e=`${o}/analysis/live/store/vscode/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"VS Code extension",t)}async scanOpenVSXExtension(s,t){let e=`${o}/analysis/live/store/openvsx/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"Open VSX extension",t)}async scanJetBrainsPlugin(s,t){let e=`${o}/analysis/live/store/jetbrains/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"JetBrains plugin",t)}async scanNpmPackage(s,t){let e=`${o}/analysis/live/store/npmjs/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericPackage(s,"npmjs",e,"npm package",t)}async scanPyPIPackage(s,t){let e=`${o}/analysis/live/store/pypi/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericPackage(s,"pypi",e,"PyPI package",t)}async scanWordPressPlugin(s,t){let e=`${o}/analysis/live/store/wordpress/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"WordPress plugin",t)}async scanHuggingFace(s,t){let e=`${o}/analysis/live/store/huggingface/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"Hugging Face model",t)}async scanAppSourceAddin(s,t){let e=`${o}/analysis/live/store/appsource/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"AppSource add-in",t)}async scanPowerShellModule(s,t){let e=`${o}/analysis/live/store/powershellgallery/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericPackage(s,"powershellgallery",e,"PowerShell module",t)}async scanSalesforceApp(s,t){let e=`${o}/analysis/live/store/salesforce/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"Salesforce app",t)}async scanByPlatform(s,t,e){if(t in w)return this.scanExtension(s,t,e);switch(t){case "vscode":return this.scanVSCodeExtension(s,e);case "openvsx":return this.scanOpenVSXExtension(s,e);case "jetbrains":return this.scanJetBrainsPlugin(s,e);case "npmjs":return this.scanNpmPackage(s,e);case "pypi":return this.scanPyPIPackage(s,e);case "wordpress":return this.scanWordPressPlugin(s,e);case "huggingface":return this.scanHuggingFace(s,e);case "appsource":return this.scanAppSourceAddin(s,e);case "powershellgallery":return this.scanPowerShellModule(s,e);default:throw new Error(`Unsupported platform: ${t}`)}}async scanGenericExtension(s,t,e,a){let i=await(await this.ensureBrowser()).newPage();try{this.reportProgress(a,{phase:"initializing",message:`Starting ${e} scan...`}),this.reportProgress(a,{phase:"navigating",message:`Navigating to ${t}`});let p=this.waitForScanResultEvent(i,"extension");if(await i.goto(t,{waitUntil:"networkidle2",timeout:this.options.timeout}),this.reportProgress(a,{phase:"scanning",message:`Waiting for ${e} analysis...`}),this.options.waitForResults){let u=await p;if(u)return this.reportProgress(a,{phase:"complete",message:"Scan complete"}),this.mapExtensionEventResult(u,s,t)}throw this.reportProgress(a,{phase:"complete",message:"Scan error"}),new Error("Scan error")}finally{await i.close();}}async scanGenericPackage(s,t,e,a,n){let p=await(await this.ensureBrowser()).newPage();try{this.reportProgress(n,{phase:"initializing",message:`Starting ${a} scan...`}),this.reportProgress(n,{phase:"navigating",message:`Navigating to ${e}`});let u=this.waitForScanResultEvent(p,"extension");if(await p.goto(e,{waitUntil:"networkidle2",timeout:this.options.timeout}),this.reportProgress(n,{phase:"scanning",message:`Waiting for ${a} analysis...`}),this.options.waitForResults){let m=await u;if(m)return this.reportProgress(n,{phase:"complete",message:"Scan complete"}),this.mapPackageEventResult(m,s,t,e)}throw this.reportProgress(n,{phase:"complete",message:"Scan error"}),new Error("Scan error")}finally{await p.close();}}async waitForScanResultEvent(s,t){return new Promise(e=>{let a=setTimeout(()=>{console.log("[Scanner] Timeout waiting for scan_result event"),e(null);},this.options.timeout);s.exposeFunction("__browsertotalScanResult",n=>{clearTimeout(a),n?.type===t?(console.log("[Scanner] Received scan_result event:",n.type),e(n)):(console.log("[Scanner] Received wrong event type:",n?.type,"expected:",t),e(null));}).catch(()=>{}),s.evaluateOnNewDocument(`
|
|
2
2
|
window.addEventListener('scan_result', function(event) {
|
|
3
3
|
console.log('[BrowserTotal] scan_result event fired');
|
|
4
4
|
if (typeof window.__browsertotalScanResult === 'function') {
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
window.__browsertotalScanResult(event.detail);
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
|
-
`).catch(()=>{});});})}mapUrlEventResult(s,t,e){let a=s.data||{};return {url:t,status:this.mapStatus(s.status,a.riskLevel),score:a.score,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),categories:a.categories,scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapExtensionEventResult(s,t,e){let a=s.data||{};return {extensionId:t,name:a.name,status:this.mapStatus(s.status,a.riskLevel),score:a.score,permissions:a.permissions,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapPackageEventResult(s,t,e,a){let n=s.data||{};return {packageName:t,platform:e,name:n.name,version:n.version,status:this.mapStatus(s.status,n.riskLevel),score:n.score,dependencies:n.dependencies,threats:n.threats?.map(i=>({type:typeof i=="string"?i:i.type||i.description,severity:i.severity||"medium",description:i.description}))||n.vulnerabilities?.map(i=>({type:i.type||i.vulnerability||i.description,severity:i.severity||"medium",description:i.description})),scanUrl:a.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapStatus(s,t){if(s==="error")return "error";let e=(t||"").toLowerCase();return e==="critical"||e==="malicious"?"malicious":e==="high"||e==="suspicious"?"suspicious":e==="safe"||e==="low"||e==="clean"?"safe":e==="medium"?"suspicious":"unknown"}async close(){this.browser&&(await this.browser.close(),this.browser=null);}};});c();async function x(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanUrl(r)}finally{await e.close();}}async function k(r,s="chrome",t){let{BrowserTotalScanner:e}=await Promise.resolve().then(()=>(c(),l)),a=new e(t);try{return await a.scanExtension(r,s)}finally{await a.close();}}async function $(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanVSCodeExtension(r)}finally{await e.close();}}async function U(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanJetBrainsPlugin(r)}finally{await e.close();}}async function B(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanNpmPackage(r)}finally{await e.close();}}async function C(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanPyPIPackage(r)}finally{await e.close();}}async function _(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanWordPressPlugin(r)}finally{await e.close();}}exports.scanExtension=k;exports.scanJetBrainsPlugin=U;exports.scanNpmPackage=B;exports.scanPyPIPackage=C;exports.scanUrl=x;exports.scanVSCodeExtension=$;exports.scanWordPressPlugin=_;
|
|
15
|
+
`).catch(()=>{});});})}mapUrlEventResult(s,t,e){let a=s.data||{};return {url:t,status:this.mapStatus(s.status,a.riskLevel),score:a.score,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),categories:a.categories,scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapExtensionEventResult(s,t,e){let a=s.data||{};return {extensionId:t,name:a.name,status:this.mapStatus(s.status,a.riskLevel),score:a.score,permissions:a.permissions,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapPackageEventResult(s,t,e,a){let n=s.data||{};return {packageName:t,platform:e,name:n.name,version:n.version,status:this.mapStatus(s.status,n.riskLevel),score:n.score,dependencies:n.dependencies,threats:n.threats?.map(i=>({type:typeof i=="string"?i:i.type||i.description,severity:i.severity||"medium",description:i.description}))||n.vulnerabilities?.map(i=>({type:i.type||i.vulnerability||i.description,severity:i.severity||"medium",description:i.description})),scanUrl:a.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapStatus(s,t){if(s==="error")return "error";let e=(t||"").toLowerCase();return e==="critical"||e==="malicious"?"malicious":e==="high"||e==="suspicious"?"suspicious":e==="safe"||e==="low"||e==="clean"?"safe":e==="medium"?"suspicious":"unknown"}async close(){this.browser&&(await this.browser.close(),this.browser=null);}async[Symbol.asyncDispose](){await this.close();}};});c();async function x(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanUrl(r)}finally{await e.close();}}async function k(r,s="chrome",t){let{BrowserTotalScanner:e}=await Promise.resolve().then(()=>(c(),l)),a=new e(t);try{return await a.scanExtension(r,s)}finally{await a.close();}}async function $(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanVSCodeExtension(r)}finally{await e.close();}}async function U(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanJetBrainsPlugin(r)}finally{await e.close();}}async function B(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanNpmPackage(r)}finally{await e.close();}}async function C(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanPyPIPackage(r)}finally{await e.close();}}async function _(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanWordPressPlugin(r)}finally{await e.close();}}exports.scanExtension=k;exports.scanJetBrainsPlugin=U;exports.scanNpmPackage=B;exports.scanPyPIPackage=C;exports.scanUrl=x;exports.scanVSCodeExtension=$;exports.scanWordPressPlugin=_;
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import S from'puppeteer';var h=Object.defineProperty;var
|
|
1
|
+
import S from'puppeteer';var h=Object.defineProperty;var y=(r,s)=>()=>(r&&(s=r(r=0)),s);var P=(r,s)=>{for(var t in s)h(r,t,{get:s[t],enumerable:true});};var l={};P(l,{BrowserTotalScanner:()=>g});function v(r){return Array.from(r).map(s=>s.charCodeAt(0).toString(16).padStart(2,"0")).join("")}var o,d,w,g,c=y(()=>{o=process.env.BROWSERTOTAL_URL||"https://browsertotal.com",d=42e4,w={chrome:"google",firefox:"mozilla",edge:"microsoft",opera:"opera",safari:"safari",brave:"brave"};g=class{options;browser=null;constructor(s={}){this.options={headless:s.headless??true,timeout:s.timeout??d,waitForResults:s.waitForResults??true,disableAI:s.disableAI??true,userDataDir:s.userDataDir};}buildHashParams(){let s=["automationEvent=true"];return this.options.disableAI&&s.push("disableAI=true"),"#"+s.join("&")}async ensureBrowser(){return this.browser||(this.browser=await S.launch({headless:this.options.headless,args:["--no-sandbox","--disable-setuid-sandbox"],userDataDir:this.options.userDataDir})),this.browser}reportProgress(s,t){s&&s(t);}async scanUrl(s,t){let a=await(await this.ensureBrowser()).newPage();try{this.reportProgress(t,{phase:"initializing",message:"Starting URL scan..."});let n=v(s),i=`${o}/analysis/urls/${n}${this.buildHashParams()}`;this.reportProgress(t,{phase:"navigating",message:`Navigating to ${i}`});let p=this.waitForScanResultEvent(a,"url");if(await a.goto(i,{waitUntil:"networkidle2",timeout:this.options.timeout}),this.reportProgress(t,{phase:"scanning",message:"Waiting for scan results..."}),this.options.waitForResults){let u=await p;if(u)return this.reportProgress(t,{phase:"complete",message:"Scan complete"}),this.mapUrlEventResult(u,s,i)}throw this.reportProgress(t,{phase:"complete",message:"Scan error"}),new Error("Scan error")}finally{await a.close();}}async scanExtension(s,t="chrome",e){let a=w[t]||t,n=`${o}/analysis/live/store/${a}/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,n,`${t} extension`,e)}async scanVSCodeExtension(s,t){let e=`${o}/analysis/live/store/vscode/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"VS Code extension",t)}async scanOpenVSXExtension(s,t){let e=`${o}/analysis/live/store/openvsx/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"Open VSX extension",t)}async scanJetBrainsPlugin(s,t){let e=`${o}/analysis/live/store/jetbrains/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"JetBrains plugin",t)}async scanNpmPackage(s,t){let e=`${o}/analysis/live/store/npmjs/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericPackage(s,"npmjs",e,"npm package",t)}async scanPyPIPackage(s,t){let e=`${o}/analysis/live/store/pypi/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericPackage(s,"pypi",e,"PyPI package",t)}async scanWordPressPlugin(s,t){let e=`${o}/analysis/live/store/wordpress/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"WordPress plugin",t)}async scanHuggingFace(s,t){let e=`${o}/analysis/live/store/huggingface/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"Hugging Face model",t)}async scanAppSourceAddin(s,t){let e=`${o}/analysis/live/store/appsource/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"AppSource add-in",t)}async scanPowerShellModule(s,t){let e=`${o}/analysis/live/store/powershellgallery/${encodeURIComponent(s)}${this.buildHashParams()}`;return this.scanGenericPackage(s,"powershellgallery",e,"PowerShell module",t)}async scanSalesforceApp(s,t){let e=`${o}/analysis/live/store/salesforce/${s}${this.buildHashParams()}`;return this.scanGenericExtension(s,e,"Salesforce app",t)}async scanByPlatform(s,t,e){if(t in w)return this.scanExtension(s,t,e);switch(t){case "vscode":return this.scanVSCodeExtension(s,e);case "openvsx":return this.scanOpenVSXExtension(s,e);case "jetbrains":return this.scanJetBrainsPlugin(s,e);case "npmjs":return this.scanNpmPackage(s,e);case "pypi":return this.scanPyPIPackage(s,e);case "wordpress":return this.scanWordPressPlugin(s,e);case "huggingface":return this.scanHuggingFace(s,e);case "appsource":return this.scanAppSourceAddin(s,e);case "powershellgallery":return this.scanPowerShellModule(s,e);default:throw new Error(`Unsupported platform: ${t}`)}}async scanGenericExtension(s,t,e,a){let i=await(await this.ensureBrowser()).newPage();try{this.reportProgress(a,{phase:"initializing",message:`Starting ${e} scan...`}),this.reportProgress(a,{phase:"navigating",message:`Navigating to ${t}`});let p=this.waitForScanResultEvent(i,"extension");if(await i.goto(t,{waitUntil:"networkidle2",timeout:this.options.timeout}),this.reportProgress(a,{phase:"scanning",message:`Waiting for ${e} analysis...`}),this.options.waitForResults){let u=await p;if(u)return this.reportProgress(a,{phase:"complete",message:"Scan complete"}),this.mapExtensionEventResult(u,s,t)}throw this.reportProgress(a,{phase:"complete",message:"Scan error"}),new Error("Scan error")}finally{await i.close();}}async scanGenericPackage(s,t,e,a,n){let p=await(await this.ensureBrowser()).newPage();try{this.reportProgress(n,{phase:"initializing",message:`Starting ${a} scan...`}),this.reportProgress(n,{phase:"navigating",message:`Navigating to ${e}`});let u=this.waitForScanResultEvent(p,"extension");if(await p.goto(e,{waitUntil:"networkidle2",timeout:this.options.timeout}),this.reportProgress(n,{phase:"scanning",message:`Waiting for ${a} analysis...`}),this.options.waitForResults){let m=await u;if(m)return this.reportProgress(n,{phase:"complete",message:"Scan complete"}),this.mapPackageEventResult(m,s,t,e)}throw this.reportProgress(n,{phase:"complete",message:"Scan error"}),new Error("Scan error")}finally{await p.close();}}async waitForScanResultEvent(s,t){return new Promise(e=>{let a=setTimeout(()=>{console.log("[Scanner] Timeout waiting for scan_result event"),e(null);},this.options.timeout);s.exposeFunction("__browsertotalScanResult",n=>{clearTimeout(a),n?.type===t?(console.log("[Scanner] Received scan_result event:",n.type),e(n)):(console.log("[Scanner] Received wrong event type:",n?.type,"expected:",t),e(null));}).catch(()=>{}),s.evaluateOnNewDocument(`
|
|
2
2
|
window.addEventListener('scan_result', function(event) {
|
|
3
3
|
console.log('[BrowserTotal] scan_result event fired');
|
|
4
4
|
if (typeof window.__browsertotalScanResult === 'function') {
|
|
@@ -12,4 +12,4 @@ import S from'puppeteer';var h=Object.defineProperty;var P=(r,s)=>()=>(r&&(s=r(r
|
|
|
12
12
|
window.__browsertotalScanResult(event.detail);
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
|
-
`).catch(()=>{});});})}mapUrlEventResult(s,t,e){let a=s.data||{};return {url:t,status:this.mapStatus(s.status,a.riskLevel),score:a.score,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),categories:a.categories,scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapExtensionEventResult(s,t,e){let a=s.data||{};return {extensionId:t,name:a.name,status:this.mapStatus(s.status,a.riskLevel),score:a.score,permissions:a.permissions,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapPackageEventResult(s,t,e,a){let n=s.data||{};return {packageName:t,platform:e,name:n.name,version:n.version,status:this.mapStatus(s.status,n.riskLevel),score:n.score,dependencies:n.dependencies,threats:n.threats?.map(i=>({type:typeof i=="string"?i:i.type||i.description,severity:i.severity||"medium",description:i.description}))||n.vulnerabilities?.map(i=>({type:i.type||i.vulnerability||i.description,severity:i.severity||"medium",description:i.description})),scanUrl:a.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapStatus(s,t){if(s==="error")return "error";let e=(t||"").toLowerCase();return e==="critical"||e==="malicious"?"malicious":e==="high"||e==="suspicious"?"suspicious":e==="safe"||e==="low"||e==="clean"?"safe":e==="medium"?"suspicious":"unknown"}async close(){this.browser&&(await this.browser.close(),this.browser=null);}};});c();async function x(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanUrl(r)}finally{await e.close();}}async function k(r,s="chrome",t){let{BrowserTotalScanner:e}=await Promise.resolve().then(()=>(c(),l)),a=new e(t);try{return await a.scanExtension(r,s)}finally{await a.close();}}async function $(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanVSCodeExtension(r)}finally{await e.close();}}async function U(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanJetBrainsPlugin(r)}finally{await e.close();}}async function B(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanNpmPackage(r)}finally{await e.close();}}async function C(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanPyPIPackage(r)}finally{await e.close();}}async function _(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanWordPressPlugin(r)}finally{await e.close();}}export{g as BrowserTotalScanner,k as scanExtension,U as scanJetBrainsPlugin,B as scanNpmPackage,C as scanPyPIPackage,x as scanUrl,$ as scanVSCodeExtension,_ as scanWordPressPlugin};
|
|
15
|
+
`).catch(()=>{});});})}mapUrlEventResult(s,t,e){let a=s.data||{};return {url:t,status:this.mapStatus(s.status,a.riskLevel),score:a.score,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),categories:a.categories,scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapExtensionEventResult(s,t,e){let a=s.data||{};return {extensionId:t,name:a.name,status:this.mapStatus(s.status,a.riskLevel),score:a.score,permissions:a.permissions,threats:a.threats?.map(n=>({type:typeof n=="string"?n:n.type||n.description,severity:n.severity||"medium",description:n.description}))||a.vulnerabilities?.map(n=>({type:n.type||n.vulnerability||n.description,severity:n.severity||"medium",description:n.description})),scanUrl:e.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapPackageEventResult(s,t,e,a){let n=s.data||{};return {packageName:t,platform:e,name:n.name,version:n.version,status:this.mapStatus(s.status,n.riskLevel),score:n.score,dependencies:n.dependencies,threats:n.threats?.map(i=>({type:typeof i=="string"?i:i.type||i.description,severity:i.severity||"medium",description:i.description}))||n.vulnerabilities?.map(i=>({type:i.type||i.vulnerability||i.description,severity:i.severity||"medium",description:i.description})),scanUrl:a.replace(/#.*$/,""),timestamp:new Date(s.timestamp||Date.now()),raw:s}}mapStatus(s,t){if(s==="error")return "error";let e=(t||"").toLowerCase();return e==="critical"||e==="malicious"?"malicious":e==="high"||e==="suspicious"?"suspicious":e==="safe"||e==="low"||e==="clean"?"safe":e==="medium"?"suspicious":"unknown"}async close(){this.browser&&(await this.browser.close(),this.browser=null);}async[Symbol.asyncDispose](){await this.close();}};});c();async function x(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanUrl(r)}finally{await e.close();}}async function k(r,s="chrome",t){let{BrowserTotalScanner:e}=await Promise.resolve().then(()=>(c(),l)),a=new e(t);try{return await a.scanExtension(r,s)}finally{await a.close();}}async function $(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanVSCodeExtension(r)}finally{await e.close();}}async function U(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanJetBrainsPlugin(r)}finally{await e.close();}}async function B(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanNpmPackage(r)}finally{await e.close();}}async function C(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanPyPIPackage(r)}finally{await e.close();}}async function _(r,s){let{BrowserTotalScanner:t}=await Promise.resolve().then(()=>(c(),l)),e=new t(s);try{return await e.scanWordPressPlugin(r)}finally{await e.close();}}export{g as BrowserTotalScanner,k as scanExtension,U as scanJetBrainsPlugin,B as scanNpmPackage,C as scanPyPIPackage,x as scanUrl,$ as scanVSCodeExtension,_ as scanWordPressPlugin};
|