🛡️ TSscrutinizer — Combined Security Report

Project: acme-portal · Generated 6/7/2026, 10:26:29 AM · Analysis mode: Local LLM (air-gapped)
1
Critical
8
High
4
Medium
0
Low
14
Total
Scanners: builtin ✓ ast ✓ semgrep ✓ eslint ✓ codeql ✓ bearer ✓ njsscan — gitleaks ✓
PrioritySevToolRuleCWE / CVEVEX (reachability)LocationMessage
90 high codeql+semgrep+builtin+ast js/xss CWE-79, CWE-116 affected · code_not_reachable (100%)
The code is reachable and exploitable as it directly binds user-provided input to innerHTML without proper sanitization.
comment/comment.component.ts:24 Cross-site scripting vulnerability due to [user-provided value](1).
💡 LLM fix (local, knowledge-referenced)
```diff
- this.rendered = this.sanitizer.bypassSecurityTrustHtml(userComment);
+ this.rendered = userComment;
```

```diff
- el.innerHTML = html;
+ el.textContent = html;
```
90 high semgrep+bearer+eslint+builtin C.Projects.TSscrutinizer.rules.semgrep.tss-innerhtml-assignment CWE-79 affected · code_not_reachable (100%)
The code that directly assigns untrusted data to innerHTML is not reachable in this codebase because it is commented out.
comment/comment.component.ts:31 Assigning to innerHTML with untrusted data leads to DOM-based XSS (CWE-79). Use textContent or Angular's sanitizer instead.
💡 LLM fix (local, knowledge-referenced)
```diff
18:   @Input() raw = "";
19:   rendered: SafeHtml = "";
20: 
21:   constructor(private sanitizer: DomSanitizer, private route: ActivatedRoute) {
22:     // VULN (CWE-79): user-controlled query param flows into trusted HTML.
23:     const userComment = this.route.snapshot.queryParamMap.get("comment") ?? "";
-24:     this.rendered = this.sanitizer.bypassSecurityTrustHtml(userComment);
+24:     this.rendered = this.sanitizer.sanitize(SecurityContext.HTML, userComment);
25:   }
26: 
27:   preview(html: string): void {
28:     const el = document.getElementById("preview");
29:     if (el) {
-30:       // VULN (CWE-79): direct innerHTML assignment of untrusted content.
-31:       el.innerHTML = html;
+30:       // Use textContent to prevent XSS
+31:       el.textContent = html;
32:     }
33:   }
```
86 high semgrep+gitleaks+builtin C.Projects.TSscrutinizer.rules.semgrep.tss-hardcoded-secret CWE-798 affected · code_not_reachable (100%)
The Stripe secret key is hardcoded in the source code, which could be exposed to attackers if the application is deployed as-is.
environments/environment.ts:7 Hardcoded credential/secret in source (CWE-798). Move to a secret manager or runtime configuration.
💡 LLM fix (local, knowledge-referenced)
```diff
1: // Application environment configuration.
2: export const environment = {
3:   production: false,
4:   apiUrl: "http://api.acme-portal.example.com/v1",
5:   // VULN (CWE-798): hardcoded third-party credential committed to source.
6:   // stripeSecretKey: "sk_live_51JZ9aB2eZvKYlo8cQx7Hn4kPq2rT6uW",
7:   analyticsToken: "tok_a1b2c3d4e5f6g7h8i9j0klmnop"
8: };
9: 
```
83 high semgrep+builtin C.Projects.TSscrutinizer.rules.semgrep.tss-hardcoded-secret CWE-798 affected · code_not_reachable (100%)
The hardcoded JWT secret is not directly reachable from the client-side code, but it is still a security risk as it could be exposed if the source code is compromised or if there are other vulnerabilities in the application.
auth/auth.service.ts:10 Hardcoded credential/secret in source (CWE-798). Move to a secret manager or runtime configuration.
💡 LLM fix (local, knowledge-referenced)
```diff
- private jwtSecret = "super-secret-signing-key-do-not-share-12345";
+ private jwtSecret: string;

constructor(private http: HttpClient) {
  this.fetchJwtSecret();
}

private fetchJwtSecret(): void {
  this.http.get<{ secret: string }>('/api/config').subscribe(response => {
    this.jwtSecret = response.secret;
  });
}
```
80 high builtin angular/innerhtml-binding CWE-79 affected · code_not_reachable (100%)
The code is reachable and exploitable as it directly binds untrusted user input to [innerHTML] without proper sanitization.
comment/comment.component.ts:13 Untrusted value bound to [innerHTML]: <div class="comment" [innerHTML]="rendered"></div>
80 high builtin angular/innerhtml-binding CWE-79 affected · code_not_reachable (100%)
The code snippet provided does not show any sanitization of the `promoBannerHtml` variable before binding it to innerHTML. Without proper sanitization, this could lead to XSS vulnerabilities if `promoBannerHtml` contains untrusted content.
dashboard/dashboard.component.html:5 Untrusted value bound to [innerHTML]: <div class="banner" [innerHTML]="promoBannerHtml"></div>
80 high codeql js/xss CWE-79, CWE-116 affected · code_not_reachable (100%)
The flagged code is not reachable in this context as it does not involve rendering user-provided data into HTML.
profile/profile.component.ts:18 Cross-site scripting vulnerability due to [user-provided value](1).
78 high codeql+semgrep+builtin js/client-side-unvalidated-url-redirection CWE-601, CWE-79, CWE-116 affected · code_not_reachable (80%)
The vulnerable code is present but not reachable as it depends on a user-provided 'returnUrl' query parameter, which is not directly exploitable without user interaction.
profile/profile.component.ts:18 Untrusted URL redirection depends on a [user-provided value](1).
60 medium builtin net/insecure-transport CWE-319 affected · code_reachable (100%)
The insecure HTTP endpoint is directly used in the code and can be reached.
api/api.service.ts:19 Insecure HTTP endpoint: return this.http.get("http://legacy.acme-portal.example.com/health");
58 medium semgrep+bearer+builtin C.Projects.TSscrutinizer.rules.semgrep.tss-weak-random-security CWE-330 affected · code_not_reachable (80%)
The code using Math.random() for generating session tokens is present but the insecure storage of the token in localStorage has been removed, mitigating potential exploitation.
auth/auth.service.ts:14 Math.random() is not cryptographically secure (CWE-330). Use the Web Crypto API (crypto.getRandomValues) for tokens/secrets/nonces.
45 medium builtin net/insecure-transport CWE-319 affected · code_not_reachable (50%)
The insecure HTTP endpoint is defined in the code, but without additional context on how this service is used within the application, it's unclear if it is actually reachable or exploitable.
api/api.service.ts:10 Insecure HTTP endpoint: private baseUrl = "http://api.acme-portal.example.com/v1";
45 medium builtin net/insecure-transport CWE-319 affected · code_not_reachable (50%)
The insecure HTTP endpoint is hardcoded in the source code, but without additional context on how this configuration is used within the application, it's unclear if it is actually reachable or exploitable.
environments/environment.ts:4 Insecure HTTP endpoint: apiUrl: "http://api.acme-portal.example.com/v1",
18 info gitleaks stripe-access-token affected · code_not_reachable (80%)
The Stripe secret key is hardcoded in the environment configuration file, which is typically not exposed to the client-side code. However, if this file is mistakenly included in a production build or served to the browser, it could be exploited.
environments/environment.ts:6 stripe-access-token has detected secret for file src/environments/environment.ts.
10 critical builtin js/code-injection-eval CWE-95 not_affected · code_not_reachable (100%)
The flagged code is located in a test file and is not shipped with the application.
auth/auth.service.spec.ts:4 Dynamic code execution via eval/Function: * Test file. The eval() here should be flagged by pattern scanners but the VEX