Setting the file. One moment.
Chapter 38 · Analyzing Code Security
Subchapter 38.2
references/vulnerability-patterns.mdMarkdown3 KBView on GitHub
CORRECT/WRONG code examples for common vulnerabilities in Bitwarden’s stack. Consult these when reviewing code or recommending fixes.
// 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 });// WRONG — insecure deserialization with type handling
JsonConvert.DeserializeObject<object>(input, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All
});
// CORRECT — no type name handling on untrusted input
JsonConvert.DeserializeObject<ExpectedType>(input);// 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);// 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);// 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);// 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// 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);// 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();// 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);
});-- 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;