diff --git a/CHANGELOG.md b/CHANGELOG.md index 5133575..06f52b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to traust-engine are documented here. +## [0.47.0] + +- **TypeScript/JavaScript rule tranche (rule pack v1.11).** New rules for the + largest uncovered TS/JS clusters in the confirmed-finding ledger: XSS + (`dangerouslySetInnerHTML`, DOM HTML sinks, `rehype-raw` without + sanitizing, reflected Express responses), path traversal (request values to + fs paths, `sendFile`, `download`) and open redirect (server redirects and + client navigation from address-bar values); SSRF gains http(s).request, + the remaining axios methods, got, superagent, needle and undici sinks. The + same rules ship on `development` (0.40.0). + ## [0.46.0] - **Code-verified versions can count as affected, with evidence.** diff --git a/VERSION b/VERSION index 3010923..421ab54 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.46.0 +0.47.0 diff --git a/pyproject.toml b/pyproject.toml index 5dc5fbf..8ef9586 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "traust-engine" -version = "0.46.0" +version = "0.47.0" license = "Apache-2.0" description = "Processing core for the AI security harness: scanners, data management, analysis, format handlers" requires-python = ">=3.11" diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/README.md b/src/traust_engine/data/secure-code-audit/opengrep-rules/README.md index a054e54..056be60 100644 --- a/src/traust_engine/data/secure-code-audit/opengrep-rules/README.md +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/README.md @@ -161,3 +161,41 @@ bound text, so a "contains" test needs a leading `.*` (`(?is).*\blike\b`), and it cannot sit directly under `pattern-either` — wrap each branch in its own `patterns:`. + +v1.11 (2026-10-27): **TypeScript/JavaScript tranche, from the ledger.** The +rule-mining report's largest uncovered TS/JS clusters were XSS (CWE-79, 37 +confirmed findings in about 30 repositories), path traversal (CWE-22, 10) +and open redirect (CWE-601, 4); each rule is written from the cited +findings' evidence. Test, spec, mock and mock-backend files are excluded. +- **XSS (`typescript/cross-site-scripting.yaml`).** + - `xss-dangerously-set-inner-html`: a computed `__html` value with no + sanitizer. Translation strings (`t(...)`, `i18n*`) and values named as + sanitized are not matched. + - `xss-dom-html-sink`: `innerHTML`/`outerHTML` assignment, + `insertAdjacentHTML`, `document.write` (also on an opened window) and + jQuery `.html()` with a computed, unsanitized value. + - `xss-markdown-raw-html` (WARNING): `rehype-raw` without a later + `rehype-sanitize`. + - `xss-reflected-response-taint`: a request value in an Express + `send`/`write`/`end` string body (sent as text/html). +- **Path traversal (`typescript/path-traversal.yaml`).** + `path-traversal-fs-taint`: a request value (query, params, body, a + destructured body field, or `req.url`/`req.path`) reaching the path + argument of an fs read, write, stream or remove, or `res.sendFile` / + `res.download`; `path.basename` and filename sanitizers clear it. +- **Open redirect (`typescript/open-redirect.yaml`).** + `open-redirect-response-taint`: a request value as the target of + `res.redirect` or a `Location` header. `open-redirect-client-navigation` + (WARNING): an address-bar value (`URLSearchParams.get`, `location.search`, + `location.hash`) as the URL of `location.assign/replace/href` or + `window.open`. +- **SSRF (`typescript/ssrf.yaml`).** More outbound sinks: `http(s).request`, + the remaining axios methods, got, superagent, needle and undici. + +Measured on eight checkouts (console, backstage, mlflow, keycloak, syndesis, +data-science-pipelines, argo-workflows, feast): 35 hits, including all three +confirmed TS/JS findings present in those checkouts (console `LogsPage.tsx`, +`SharedResourceWarning.js`, `backend/src/routes/serve.ts`). Precision is +unmeasured until the facts are judged (`/mine-ledger`). Not covered: +`javascript:` URLs bound to `href`, markdown-to-jsx and marked renderer +overrides, and sanitize-then-transform pipelines; these stay with review. diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/cross-site-scripting.tsx b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/cross-site-scripting.tsx new file mode 100644 index 0000000..2dd066a --- /dev/null +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/cross-site-scripting.tsx @@ -0,0 +1,82 @@ +import DOMPurify from "dompurify"; +import ReactMarkdown from "react-markdown"; +import rehypeRaw from "rehype-raw"; +import rehypeSanitize from "rehype-sanitize"; +import $ from "jquery"; + +export const Entry = ({ response }: { response: string }) => ( + // ruleid: traust-ts-xss-dangerously-set-inner-html +
+); + +export const Clean = ({ response }: { response: string }) => ( + // ok: traust-ts-xss-dangerously-set-inner-html +
+); + +// ok: traust-ts-xss-dangerously-set-inner-html +export const Fixed = () =>
static" }} />; + +export const Help = ({ t, i18nDescription, sanitizedContent }: any) => ( + <> + {/* ok: traust-ts-xss-dangerously-set-inner-html */} +

+ {/* ok: traust-ts-xss-dangerously-set-inner-html */} +

+ {/* ok: traust-ts-xss-dangerously-set-inner-html */} +

+ +); + +export const Warning = ({ t, resources }: any) => ( + // ruleid: traust-ts-xss-dangerously-set-inner-html +

+); + +export function openRawTab(logs: string): void { + const rawWindow = window.open("about:blank"); + // ruleid: traust-ts-xss-dom-html-sink + rawWindow?.document.write(`

${logs}
`); + // ok: traust-ts-xss-dom-html-sink + document.write("

loading

"); +} + +export async function loadConfig(response: Response): Promise { + const script = await response.text(); + const configScript = document.createElement("script"); + // ruleid: traust-ts-xss-dom-html-sink + configScript.innerHTML = script; + const box = document.getElementById("box")!; + // ok: traust-ts-xss-dom-html-sink + box.innerHTML = ""; + // ok: traust-ts-xss-dom-html-sink + box.innerHTML = DOMPurify.sanitize(script); + // ruleid: traust-ts-xss-dom-html-sink + box.insertAdjacentHTML("beforeend", script); + // ruleid: traust-ts-xss-dom-html-sink + $("#answers").html(marked.parse(script)); + // ok: traust-ts-xss-dom-html-sink + box.textContent = script; +} + +export const Docs = ({ text }: { text: string }) => ( + // ruleid: traust-ts-xss-markdown-raw-html + {text} +); + +export const SafeDocs = ({ text }: { text: string }) => ( + // ok: traust-ts-xss-markdown-raw-html + {text} +); + +export function bundle(req: any, res: any): void { + const sha = req.params.sha; + // ruleid: traust-ts-xss-reflected-response-taint + res.status(404).send(`Bundle ${sha} not found`); + // ruleid: traust-ts-xss-reflected-response-taint + res.send("unknown filetype " + req.query.filetype); + // ok: traust-ts-xss-reflected-response-taint + res.status(404).send(`Bundle ${escapeHtml(sha)} not found`); + // ok: traust-ts-xss-reflected-response-taint + res.json({ error: `Bundle ${sha} not found` }); +} diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/cross-site-scripting.yaml b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/cross-site-scripting.yaml new file mode 100644 index 0000000..1530353 --- /dev/null +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/cross-site-scripting.yaml @@ -0,0 +1,168 @@ +rules: + - id: traust-ts-xss-dangerously-set-inner-html + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: ERROR + message: >- + A computed value is rendered as raw HTML through dangerouslySetInnerHTML + with no sanitizer — markup from log lines, WebSocket messages or API + data runs as script in the viewer's session. Render it as text, or pass + it through DOMPurify.sanitize first. CWE-79. + metadata: + cwe: ["CWE-79"] + category: cross-site-scripting + asvs: ["V5"] + confidence: MEDIUM + references: + - "CWE-79 DOM XSS — unsanitized dangerouslySetInnerHTML" + patterns: + - pattern: "{__html: $X}" + - pattern-not: "{__html: \"...\"}" + - pattern-not: "{__html: $SAN.sanitize(...)}" + - pattern-not: "{__html: sanitize(...)}" + - pattern-not: "{__html: sanitizeHtml(...)}" + - pattern-not: "{__html: DOMPurify.sanitize(...)}" + - pattern-not: "{__html: xss(...)}" + # translation strings and already-sanitized values: `t(...)`, `i18nX`, `props.i18nX(...)`, + # `sanitizedContent` + - metavariable-regex: + metavariable: $X + regex: (?is)^(?!\s*(?:[\w$]+\.)*(?:t|i18n\w*|sanitiz\w*|purif\w*)\b) + + - id: traust-ts-xss-dom-html-sink + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: ERROR + message: >- + A computed value is written into the page as HTML (innerHTML, + outerHTML, insertAdjacentHTML, document.write or jQuery .html()) with + no sanitizer — markup in it executes as script. Use textContent, or + sanitize with DOMPurify first. CWE-79. + metadata: + cwe: ["CWE-79"] + category: cross-site-scripting + asvs: ["V5"] + confidence: MEDIUM + references: + - "CWE-79 DOM XSS — HTML sink fed a computed value" + patterns: + - pattern-either: + - pattern: $E.innerHTML = $X + - pattern: $E.outerHTML = $X + - pattern: $E.insertAdjacentHTML($POS, $X) + - pattern: document.write($X) + - pattern: document.writeln($X) + - pattern: $W.document.write($X) + - pattern: $J($SEL).html($X) + - pattern-not: $E.innerHTML = "..." + - pattern-not: $E.innerHTML = "" + - pattern-not: $E.outerHTML = "..." + - pattern-not: $E.insertAdjacentHTML($POS, "...") + - pattern-not: document.write("...") + - pattern-not: $W.document.write("...") + - pattern-not: $J($SEL).html("...") + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-not: $SAN.sanitize(...) + - pattern-not: sanitize(...) + - pattern-not: sanitizeHtml(...) + - pattern-not: escapeHtml(...) + + - id: traust-ts-xss-markdown-raw-html + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: WARNING + message: >- + Markdown is rendered with raw HTML enabled (rehype-raw) and no + rehype-sanitize step — HTML embedded in the Markdown source reaches the + page unfiltered. Add rehype-sanitize after rehype-raw, or drop raw HTML. + CWE-79. + metadata: + cwe: ["CWE-79"] + category: cross-site-scripting + asvs: ["V5"] + confidence: MEDIUM + references: + - "CWE-79 stored XSS — Markdown renderer passing raw HTML" + patterns: + - pattern: "[..., rehypeRaw, ...]" + - pattern-not: "[..., rehypeRaw, ..., rehypeSanitize, ...]" + - pattern-not: "[..., rehypeRaw, ..., [rehypeSanitize, ...], ...]" + + - id: traust-ts-xss-reflected-response-taint + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: ERROR + message: >- + A request value is echoed into a response body that Express sends as + text/html — markup in the path, query or body runs in the caller's + browser (reflected XSS). Return JSON, set a text/plain content type, or + HTML-escape the value. CWE-79. + metadata: + cwe: ["CWE-79"] + category: cross-site-scripting + asvs: ["V5"] + confidence: MEDIUM + references: + - "CWE-79 reflected XSS — request value in an HTML response body" + mode: taint + pattern-sources: + - pattern-either: + - pattern: $REQ.query.$P + - pattern: $REQ.params.$P + - pattern: $REQ.body.$P + - pattern: $REQ.query[$K] + - pattern: $REQ.params[$K] + pattern-sanitizers: + - pattern-either: + - pattern: escapeHtml(...) + - pattern: $X.escape(...) + - pattern: encodeURIComponent(...) + - pattern: JSON.stringify(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.send(`...`) + - pattern: $RES.send("..." + $X) + - pattern: $RES.send($X + "...") + - pattern: $RES.status($C).send(`...`) + - pattern: $RES.status($C).send("..." + $X) + - pattern: $RES.write(`...`) + - pattern: $RES.end(`...`) diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/open-redirect.ts b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/open-redirect.ts new file mode 100644 index 0000000..f61ac03 --- /dev/null +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/open-redirect.ts @@ -0,0 +1,23 @@ +export function callback(req: any, res: any): void { + // ruleid: traust-ts-open-redirect-response-taint + res.redirect(req.query.next); + // ruleid: traust-ts-open-redirect-response-taint + res.redirect(302, req.query.returnTo); + // ok: traust-ts-open-redirect-response-taint + res.redirect("/login"); + // ruleid: traust-ts-open-redirect-response-taint + res.setHeader("Location", req.query.next); +} + +export function afterLogin(): void { + const params = new URLSearchParams(window.location.search); + const target = params.get("redirect"); + // ruleid: traust-ts-open-redirect-client-navigation + window.location.assign(target); + // ok: traust-ts-open-redirect-client-navigation + window.location.assign("/home"); + // ruleid: traust-ts-open-redirect-client-navigation + window.open(window.location.hash.slice(1), "_blank"); + // ok: traust-ts-open-redirect-client-navigation + window.open("/graph", params.get("target") || "_top"); +} diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/open-redirect.yaml b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/open-redirect.yaml new file mode 100644 index 0000000..016b544 --- /dev/null +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/open-redirect.yaml @@ -0,0 +1,96 @@ +rules: + - id: traust-ts-open-redirect-response-taint + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: ERROR + message: >- + A request value is used as a redirect target — the caller can send users + to any site with this host's link (phishing, OAuth code or token + theft). Redirect only to relative paths or an allowlisted origin. + CWE-601. + metadata: + cwe: ["CWE-601"] + category: open-redirect + asvs: ["V5"] + confidence: HIGH + references: + - "CWE-601 open redirect — request value as the redirect target" + mode: taint + pattern-sources: + - pattern-either: + - pattern: $REQ.query.$P + - pattern: $REQ.params.$P + - pattern: $REQ.body.$P + - pattern: $REQ.query[$K] + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.redirect($URL) + - pattern: $RES.redirect($CODE, $URL) + - patterns: + - pattern: $RES.setHeader($H, $URL) + - metavariable-regex: + metavariable: $H + regex: (?i)^["']location["']$ + - focus-metavariable: $URL + + - id: traust-ts-open-redirect-client-navigation + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: WARNING + message: >- + The page navigates to a URL taken from the address bar (query string or + fragment) — a crafted link sends the user to any site, or runs a + javascript: URL in this origin. Navigate only to relative paths or an + allowlisted origin and scheme. CWE-601. + metadata: + cwe: ["CWE-601", "CWE-79"] + category: open-redirect + asvs: ["V5"] + confidence: MEDIUM + references: + - "CWE-601 client-side open redirect — address-bar value as the navigation target" + mode: taint + pattern-sources: + - pattern-either: + - pattern: new URLSearchParams(...).get(...) + - pattern: $U.searchParams.get(...) + - patterns: + - pattern: $PARAMS.get(...) + - metavariable-regex: + metavariable: $PARAMS + regex: (?i)^(params|searchParams|urlParams|queryParams|query|search)$ + - pattern: window.location.search + - pattern: window.location.hash + - pattern: location.search + - pattern: location.hash + pattern-sinks: + - patterns: + - pattern-either: + - pattern: window.location.href = $URL + - pattern: window.location = $URL + - pattern: location.href = $URL + - pattern: window.location.assign($URL) + - pattern: window.location.replace($URL) + - pattern: location.assign($URL) + - pattern: location.replace($URL) + - pattern: window.open($URL, ...) + - focus-metavariable: $URL diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/path-traversal.ts b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/path-traversal.ts new file mode 100644 index 0000000..bb6953b --- /dev/null +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/path-traversal.ts @@ -0,0 +1,38 @@ +import fs, { createReadStream } from "fs"; +import fsp from "fs/promises"; +import path from "path"; + +export async function saveConfig(req: any, res: any): Promise { + const { config, name } = req.body; + const filepath = path.join(CONFIGS_DIR, name); + // ruleid: traust-ts-path-traversal-fs-taint + await fsp.writeFile(filepath, config); + // ok: traust-ts-path-traversal-fs-taint + await fsp.writeFile(path.join(CONFIGS_DIR, "latest.yaml"), req.body.config); + res.json({ ok: true }); +} + +export async function readLog(req: any, res: any): Promise { + const logFile = path.join(LOGS_DIR, `${req.params.id}.log`); + // ruleid: traust-ts-path-traversal-fs-taint + const logs = await fsp.readFile(logFile, "utf8"); + // ok: traust-ts-path-traversal-fs-taint + const safe = await fsp.readFile(path.join(LOGS_DIR, path.basename(req.params.id)), "utf8"); + res.send(logs + safe); +} + +export function servePublic(req: any, res: any): void { + const url = req.url.split("?")[0]; + const filePath = `${publicFolder}${url}`; + // ruleid: traust-ts-path-traversal-fs-taint + createReadStream(filePath).pipe(res); +} + +export function serve(req: any, res: any): void { + // ruleid: traust-ts-path-traversal-fs-taint + res.sendFile(path.join(STATIC_DIR, req.query.file)); + // ok: traust-ts-path-traversal-fs-taint + res.sendFile(path.join(STATIC_DIR, "index.html")); + // ok: traust-ts-path-traversal-fs-taint + fs.readFileSync(path.join(__dirname, "template.html"), "utf8"); +} diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/path-traversal.yaml b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/path-traversal.yaml new file mode 100644 index 0000000..3d30829 --- /dev/null +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/path-traversal.yaml @@ -0,0 +1,88 @@ +rules: + - id: traust-ts-path-traversal-fs-taint + languages: [typescript, javascript] + paths: + exclude: + - "*.test.*" + - "*.spec.*" + - "*/__tests__/*" + - "*/__mocks__/*" + - "*/mock-backend/*" + - "*/mocks/*" + - "*/test/*" + - "*/tests/*" + severity: ERROR + message: >- + A request value becomes part of a filesystem path that is read, written, + removed or served — `../` segments in it reach files outside the + intended directory. Reduce it to a basename, or resolve the joined path + and check it is still inside the base directory before using it. CWE-22. + metadata: + cwe: ["CWE-22", "CWE-73"] + category: path-traversal + asvs: ["V12"] + confidence: HIGH + references: + - "CWE-22 path traversal — request value joined into a filesystem path" + mode: taint + pattern-sources: + - pattern-either: + - pattern: $REQ.query.$P + - pattern: $REQ.params.$P + - pattern: $REQ.body.$P + - pattern: $REQ.query[$K] + - pattern: $REQ.params[$K] + - patterns: + - pattern-either: + - pattern: $R.url + - pattern: $R.originalUrl + - pattern: $R.path + - metavariable-regex: + metavariable: $R + regex: ^(req|request)$ + - patterns: + - pattern-inside: "const {...} = $REQ.$PART;" + - pattern: $V + - metavariable-regex: + metavariable: $PART + regex: ^(query|params|body)$ + pattern-sanitizers: + - pattern-either: + - pattern: path.basename(...) + - pattern: basename(...) + - pattern: sanitizeFilename(...) + - pattern: sanitize(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $FS.readFile($P, ...) + - pattern: $FS.readFileSync($P, ...) + - pattern: $FS.writeFile($P, ...) + - pattern: $FS.writeFileSync($P, ...) + - pattern: $FS.appendFile($P, ...) + - pattern: $FS.createReadStream($P, ...) + - pattern: $FS.createWriteStream($P, ...) + - pattern: $FS.unlink($P, ...) + - pattern: $FS.unlinkSync($P, ...) + - pattern: $FS.rm($P, ...) + - pattern: $FS.rmSync($P, ...) + - pattern: $FS.promises.readFile($P, ...) + - pattern: $FS.promises.writeFile($P, ...) + - pattern: readFile($P, ...) + - pattern: readFileSync($P, ...) + - pattern: writeFile($P, ...) + - pattern: writeFileSync($P, ...) + - pattern: createReadStream($P, ...) + - pattern: createWriteStream($P, ...) + - pattern: unlink($P, ...) + - pattern: unlinkSync($P, ...) + - pattern: rmSync($P, ...) + - focus-metavariable: $P + - patterns: + - pattern-either: + - pattern: $RES.sendFile($P, ...) + - pattern: $RES.download($P, ...) + - metavariable-regex: + metavariable: $RES + regex: ^(res|response|ctx)$ + - focus-metavariable: $P diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.ts b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.ts index 194ce83..f6f4846 100644 --- a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.ts +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.ts @@ -10,4 +10,13 @@ export async function proxy(req: any, res: any): Promise { // ok: traust-ts-ssrf-request-taint await fetch("https://api.openshift.com/healthz"); + + // ruleid: traust-ts-ssrf-request-taint + await got.get(req.body.webhookUrl); + + // ruleid: traust-ts-ssrf-request-taint + https.request(req.query.callback, () => undefined); + + // ruleid: traust-ts-ssrf-request-taint + await axios.request({ url: req.body.target }); } diff --git a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.yaml b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.yaml index beba6e5..b9820b9 100644 --- a/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.yaml +++ b/src/traust_engine/data/secure-code-audit/opengrep-rules/typescript/ssrf.yaml @@ -28,3 +28,19 @@ rules: - pattern: axios(...) - pattern: http.get(...) - pattern: https.get(...) + - pattern: http.request(...) + - pattern: https.request(...) + - pattern: axios.put(...) + - pattern: axios.patch(...) + - pattern: axios.delete(...) + - pattern: axios.head(...) + - pattern: axios.request(...) + - pattern: got(...) + - pattern: got.get(...) + - pattern: got.post(...) + - pattern: superagent.get(...) + - pattern: superagent.post(...) + - pattern: needle(...) + - pattern: needle.get(...) + - pattern: undici.request(...) + - pattern: undici.fetch(...) diff --git a/uv.lock b/uv.lock index 222834a..96b1820 100644 --- a/uv.lock +++ b/uv.lock @@ -2086,7 +2086,7 @@ dependencies = [ [[package]] name = "traust-engine" -version = "0.46.0" +version = "0.47.0" source = { editable = "." } dependencies = [ { name = "jsonschema" },