Skip to content
Language guides Reviewed 2026-09-12

JavaScript secure coding

JavaScript runs in different trust environments. Browser code must protect the DOM from untrusted markup; Node.js and Express services must also protect databases, files and outbound requests. This example focuses on displaying a plain-text message in a browser. It is equally relevant when the value came from a trusted-looking API that stores user content.

Choose a text sink

Assume message is an untrusted string and output is an existing element selected by your application.

Unsafe: ask the browser to parse the message as markup.

output.innerHTML = message;

Safer for plain text: assign a text value.

output.textContent = message;

textContent makes the value text. HTML-looking characters are displayed rather than interpreted as elements. This is appropriate for names, comments, status labels and other fields that do not require markup. MDN documents the difference between textContent and innerHTML.

If the product deliberately allows rich text, define an allowed HTML policy and use a maintained sanitizer suited to that policy. Do not turn escaping off just to preserve formatting. URL attributes, JavaScript strings and CSS need their own handling; plain-text protection is not a general sanitizer for every context. OWASP's XSS prevention guidance explains these distinctions.

Check the fix

Set message to the harmless string <b>Demo label</b> in a local component test. Assert that the output contains those literal characters and that output.querySelector('b') returns null. Verify ordinary text, Unicode and empty values still render correctly. This test does not need to execute an attack script.

For server code, keep SQL values parameterized, avoid shell command construction, and allowlist outbound destinations where possible. Validate object keys before merging user data into configuration; using JavaScript objects does not automatically make a merge safe.

Continue with DOM XSS, command injection, SQL injection and the TypeScript guide. Browser and server examples explain source-level risks; scanner results depend on the supported runtime, frameworks and enabled checks.