DepWarden's free JavaScript and TypeScript SAST scanner checks JavaScript and TypeScript source code against 82 security rules (including 5 Express-specific, 9 React-specific, 9 Angular-specific rules). Every rule maps to a CWE and the findings span 8 OWASP Top 10 categories, and every finding comes with an explanation, a fix and a before-and-after example. Paste a file, upload a zip or connect a repository: no account, and the results stay in a private, session-isolated workspace.
JavaScript and TypeScript cover both sides of the web: Node.js and Express back ends, and React or Angular front ends. The same language runs code that talks to the database and code that renders user-supplied text in a browser, so injection and cross-site scripting are the classic risks.
82 rules cover 43 distinct weakness types (13 critical, 31 high, 29 medium and 9 low severity).
| What it checks | Rules | Examples |
|---|---|---|
| Injection (SQL, command, code) | 18 | Angular bypassSecurityTrustScript enables direct code execution; Angular runtime JIT compilation of a dynamic template; child_process shell string from user input |
| Insecure configuration | 14 | CORS wildcard origin with credentials; CORS: Access-Control-Allow-Credentials with wildcard origin; Cookie missing HttpOnly / Secure |
| Weak cryptography | 14 | MD5 used for password hashing; TLS certificate validation disabled — trust all certs; TLS hostname verification skipped |
| Cross-site scripting | 8 | Angular bypassSecurityTrustHtml disables XSS sanitization; Angular bypassSecurityTrustUrl/ResourceUrl disables URL sanitization; Angular DomSanitizer.sanitize(SecurityContext.NONE, ...) disables all sanitization |
| Authentication and sessions | 6 | JWT decoded without signature verification; JWT none algorithm accepted; JWT verification weakened (alg none / no verify) |
| Server-side request forgery | 4 | SSRF — HTTP request to user-controlled URL; Angular HttpClient request to a URL that may be user-controlled; iframe src set from user-controlled data |
| Hardcoded secrets | 3 | Hardcoded symmetric encryption key; JWT signed with weak or hardcoded secret; API key or token in URL query string |
| Open redirect | 3 | Open redirect to user-controlled URL; Angular Router.navigate/navigateByUrl to an unvalidated target; react-router redirect/navigate to an unvalidated target |
| Privacy and data leaks | 3 | redux-persist whitelisting an auth/token slice; Sensitive data written to application log; console.log / console.debug in production code |
| Access control | 2 | Open redirect; Next.js API route handler doesn't check req.method |
| Reliability and error handling | 2 | debugger statement in production code; Loose equality (== / !=) with potentially type-confused operands |
| Denial of service | 1 | Potential ReDoS (catastrophic backtracking) |
| File handling | 1 | File upload without type or size restriction |
| Insecure deserialization | 1 | Insecure deserialization (node-serialize) |
| Mass assignment | 1 | Mass assignment from request body to model |
| Path traversal | 1 | Path traversal in file access |
bypassSecurityTrustScript marks a string as safe executable script — the most dangerous Angular sanitizer bypass. Untrusted input here is direct code execution in the browser.
Vulnerable:
const safeScript = this.sanitizer.bypassSecurityTrustScript(config.customScript);Fixed:
// Avoid dynamic script injection; load fixed, versioned scripts via <script src> in index.html insteadRemove bypassSecurityTrustScript entirely; there is almost never a legitimate need for dynamic script injection in an Angular app.
node-serialize.unserialize() executes embedded functions, enabling RCE on untrusted input.
Vulnerable:
const obj = serialize.unserialize(req.body.data);Fixed:
const obj = JSON.parse(req.body.data);Use JSON.parse for untrusted data. Do not use node-serialize / funcster on attacker-controlled input.
bypassSecurityTrustHtml() marks a string as safe HTML, disabling Angular's built-in XSS sanitization. If the input contains untrusted data, this enables XSS.
Vulnerable:
this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(comment.body);Fixed:
this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(DOMPurify.sanitize(comment.body));Avoid bypassSecurityTrustHtml on user-controlled data. Let Angular's default sanitizer handle untrusted HTML, or run it through DOMPurify first if bypass is unavoidable.
- uses: Rushabh5000/depwarden-action@v1
with:
sast-dir: src
sast-fail-on: high
env:
APP_API_KEY: ${{ secrets.APP_API_KEY }}DepWarden's SAST engine uses pattern rules and taint-aware rules that require untrusted input to reach a dangerous call. It is not a full cross-file dataflow engine, so a bug that only appears when data crosses several files can be missed, and every static analyser reports some false positives. Treat findings as leads: review them, fix the real ones and suppress the rest with a written reason. SAST covers the code you write; for the packages you import, run software composition analysis too.
Yes. DepWarden's JavaScript and TypeScript scanner is free in the browser with no account: paste code, upload a zip or connect a repository. Running SAST from CI through an API key needs a plan that includes SAST.
.js, .jsx, .mjs, .cjs, .ts, .tsx, .mts, .cts. Configuration and secret-bearing files such as .env and key files are also checked for hardcoded credentials, whatever language the project uses.
Each finding names the weakness (CWE), explains why the code is risky, shows a vulnerable and a fixed version of the pattern, and gives the remediation. Fix the code, then scan again to confirm the finding is gone.
Other languages: Python, Java, PHP, Go (Golang), C#, Ruby, Kotlin, Swift, and secret scanning. Compare the options in free SAST tools compared, or start with what is SAST and SAST vs SCA.