diff --git a/src/command/runner.ts b/src/command/runner.ts index b157e41..d012592 100644 --- a/src/command/runner.ts +++ b/src/command/runner.ts @@ -1,5 +1,6 @@ import { err, errAsync, ok, okAsync, Result, ResultAsync } from "neverthrow"; +import { URLScan } from "~/scanner"; import type { OptionsType } from "~/schemas"; import { Selector } from "~/selector"; import type { @@ -139,6 +140,7 @@ export class CommandRunner { break; case "urlscan.io": scanner.setAPIKey(this.options.urlscanAPIKey); + (scanner as URLScan).setVisibility(this.options.urlscanVisibility); break; case "VirusTotal": scanner.setAPIKey(this.options.virusTotalAPIKey); diff --git a/src/options/index.vue b/src/options/index.vue index 7b14b4e..513862e 100644 --- a/src/options/index.vue +++ b/src/options/index.vue @@ -10,7 +10,7 @@ import "bulma/css/bulma.css"; import { onMounted, reactive, ref, watch } from "vue"; import { Scanners } from "../scanner"; -import type { OptionsType, SearchableType } from "../schemas"; +import { OptionsType, SearchableType } from "../schemas"; import { Searchers } from "../searcher"; import { getOptions, setOptions } from "../storage"; import type { ScannableType, Scanner, Searcher } from "../types"; @@ -31,6 +31,7 @@ const options = reactive({ strict: true, hybridAnalysisAPIKey: undefined, urlscanAPIKey: undefined, + urlscanVisibility: "public", virusTotalAPIKey: undefined, disabledScannerNames: [], disabledSearcherNames: [], @@ -267,6 +268,23 @@ watch(options, async (newOptions) => { /> +
+ +
+
+ +
+
+
diff --git a/src/scanner/urlscan.ts b/src/scanner/urlscan.ts index bb0f56e..cd8fe4a 100644 --- a/src/scanner/urlscan.ts +++ b/src/scanner/urlscan.ts @@ -1,6 +1,7 @@ import { errAsync, ResultAsync } from "neverthrow"; import * as v from "valibot"; +import type { urlscanVisibilityType } from "~/schemas"; import type { ScannableType } from "~/types"; import { Base } from "./base"; @@ -19,6 +20,7 @@ export class URLScan extends Base { public name: string; public supportedTypes: ScannableType[] = ["ip", "domain", "url"]; public apiKey?: string = undefined; + public visibility: urlscanVisibilityType = "public"; public constructor() { super(); @@ -30,6 +32,10 @@ export class URLScan extends Base { this.apiKey = apiKey; } + public setVisibility(visibility: urlscanVisibilityType): void { + this.visibility = visibility; + } + scanByIP(ip: string) { return this.scan(ip); } @@ -42,25 +48,22 @@ export class URLScan extends Base { return this.scan(url); } - private scan(query: string, isPublic = true) { + private scan(query: string) { if (!this.apiKey) { return errAsync("Please set your urlscan.io API key via the option."); } - const body = JSON.stringify({ - public: isPublic ? "on" : "off", - url: query, - }); - const headers = { - "API-KEY": this.apiKey, - "content-type": "application/json", - }; - const scan = async () => { const res = await fetch(`${this.baseURL}/api/v1/scan/`, { method: "POST", - headers, - body, + headers: { + "API-KEY": this.apiKey!, + "content-type": "application/json", + }, + body: JSON.stringify({ + visibility: this.visibility, + url: query, + }), }); const data = await res.json(); diff --git a/src/schemas.ts b/src/schemas.ts index 3e88943..8c0be9f 100644 --- a/src/schemas.ts +++ b/src/schemas.ts @@ -9,12 +9,21 @@ export const SelectorOptionsSchema = v.object({ export type SelectorOptionsType = v.InferOutput; +export const urlscanVisibility = v.union([ + v.literal("public"), + v.literal("unlisted"), + v.literal("private"), +]); + +export type urlscanVisibilityType = v.InferOutput; + export const OtherOptionsSchema = v.object({ href: v.optional(v.boolean(), true), disabledSearcherNames: v.optional(v.array(v.string()), []), disabledScannerNames: v.optional(v.array(v.string()), []), hybridAnalysisAPIKey: v.optional(v.string()), urlscanAPIKey: v.optional(v.string()), + urlscanVisibility: v.optional(urlscanVisibility, "public"), virusTotalAPIKey: v.optional(v.string()), }); diff --git a/src/storage.ts b/src/storage.ts index 64dc1b5..71fa9e1 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -26,6 +26,7 @@ export async function setOptions(options: OptionsType): Promise { disabledScannerNames: options.disabledScannerNames.map((n) => n), hybridAnalysisAPIKey: options.hybridAnalysisAPIKey, urlscanAPIKey: options.urlscanAPIKey, + urlscanVisibility: options.urlscanVisibility, virusTotalAPIKey: options.virusTotalAPIKey, }, });