# Language-Specific Vulnerability Patterns CORRECT/WRONG code examples for common vulnerabilities in Bitwarden's stack. Consult these when reviewing code or recommending fixes. ## C# / .NET ```csharp // WRONG — SQL injection via string concatenation var query = $"SELECT * FROM Users WHERE Id = '{userId}'"; var result = connection.Execute(query); // CORRECT — parameterized query var query = "SELECT * FROM Users WHERE Id = @UserId"; var result = connection.Execute(query, new { UserId = userId }); ``` ```csharp // WRONG — insecure deserialization with type handling JsonConvert.DeserializeObject(input, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); // CORRECT — no type name handling on untrusted input JsonConvert.DeserializeObject(input); ``` ```csharp // WRONG — path traversal via user input var filePath = Path.Combine(baseDir, userInput); var content = File.ReadAllText(filePath); // CORRECT — canonicalize and validate var filePath = Path.GetFullPath(Path.Combine(baseDir, userInput)); if (!filePath.StartsWith(Path.GetFullPath(baseDir))) throw new UnauthorizedAccessException(); var content = File.ReadAllText(filePath); ``` ```csharp // WRONG — SSRF via user-controlled URL var response = await httpClient.GetAsync(userProvidedUrl); // CORRECT — validate against allowlist var uri = new Uri(userProvidedUrl); if (!AllowedHosts.Contains(uri.Host)) throw new ArgumentException("Host not allowed"); var response = await httpClient.GetAsync(uri); ``` ```csharp // WRONG — XXE via default XML settings var doc = new XmlDocument(); doc.LoadXml(userInput); // CORRECT — disable DTD and external entities var doc = new XmlDocument(); doc.XmlResolver = null; doc.LoadXml(userInput); ``` ## TypeScript / Angular ```typescript // WRONG — XSS via innerHTML element.innerHTML = userInput; // CORRECT — use framework text binding // In Angular templates: {{ userInput }} (auto-escaped) // Or use DomSanitizer with explicit trust only for known-safe content ``` ```typescript // WRONG — bypassing Angular security without justification this.sanitizer.bypassSecurityTrustHtml(userInput); // CORRECT — only bypass for content fully controlled by the application const trustedContent = this.generateSafeHtml(); // no user input this.sanitizer.bypassSecurityTrustHtml(trustedContent); ``` ```typescript // WRONG — open redirect window.location.href = params.get("redirect"); // CORRECT — validate redirect target const redirect = params.get("redirect"); const url = new URL(redirect, window.location.origin); if (url.origin !== window.location.origin) { throw new Error("Invalid redirect"); } window.location.href = url.toString(); ``` ```typescript // WRONG — insecure postMessage (no origin check) window.addEventListener("message", (event) => { processData(event.data); }); // CORRECT — validate origin window.addEventListener("message", (event) => { if (event.origin !== "https://expected-origin.com") return; processData(event.data); }); ``` ## SQL ```sql -- WRONG — dynamic SQL with concatenation EXECUTE('SELECT * FROM Users WHERE Name = ''' + @Name + ''''); -- CORRECT — parameterized dynamic SQL EXECUTE sp_executesql N'SELECT * FROM Users WHERE Name = @Name', N'@Name NVARCHAR(100)', @Name = @Name; ```