CodeBlanks Logo Icon CodeBlanks

Project final - Secure comments

JavaScript course · Expert · Lesson 35/63

Finalize the comments app with XSS-safe rendering and CSP enforcement.

Final integration

In the final lesson we'll combine all parts and finish the app. The form handler reads the comment, adds it safely with renderComment, then clears the input.

We start the app with an initApp function: it focuses the input and makes it ready.

Now our app has three layers of protection: textContent, escapeHtml and CSP.

What we built

At the end of five lessons we've built a secure comments app:

  • Capturing comments with a form submit listener
  • XSS-safe rendering with textContent
  • An extra encoding layer with escapeHtml
  • A CSP meta tag to restrict scripts
  • Input clearing and startup with initApp

The app is now ready for production use.

Exercise Finish the app

Add the line commentInput.value = ""; to the submit handler (after the renderComment call) so the input clears after each comment. Then define an initApp function that calls commentForm.querySelector("#commentText").focus() inside. Finally call initApp() to start the app.

Show example solution
commentForm.addEventListener("submit", (event) => {
  event.preventDefault();
  const commentInput = commentForm.querySelector("#commentText");
  const text = commentInput.value;
  renderComment(text);
  commentInput.value = "";
});

function initApp() {
  commentForm.querySelector("#commentText").focus();
}
initApp();

Test yourself

  1. Three layers of protection

    textContent + escapeHtml + CSP
    • Only CSP is enough
    • Only escapeHtml is enough
    • textContent + escapeHtml + CSP together
    • innerHTML + CSP is enough
    Show answer

    textContent + escapeHtml + CSP together — Correct! Defense in depth: textContent + escapeHtml + CSP.

  2. Call initApp

    function initApp() {
      commentForm.querySelector("#commentText").focus();
    }
    ____
    Show answer
    function initApp() {
      commentForm.querySelector("#commentText").focus();
    }
    initApp();
  3. Match threats to defenses

    XSS
    Prevented with textContent
    Inline script
    Blocked by CSP
    HTML injection
    Encoded with escapeHtml
    Page reload
    Stopped with preventDefault

All lessons in Expert