Javascript Interview - Intermediate
What is de-structuring in JavaScript?
Destructuring in JavaScript is a syntax feature that allows you to unpack values from arrays or properties from objects into distinct variables. It makes extracting data much more concise and readable.
i) Array Destructuring// You can extract values from an array and assign them to variables const numbers = [1, 2, 3]; const [a, b, c] = numbers; console.log(a); // 1 console.log(b); // 2 console.log(c); // 3 // You can also skip elements const [first, , third] = numbers; console.log(third); // 3ii) Object Destructuring
// You can extract values from an object by matching property names const person = { name: 'Alice', age: 25 }; const { name, age } = person; console.log(name); // Alice console.log(age); // 25 // You can also rename variables const { name: fullName } = person; console.log(fullName); // AliceHow does object destructuring differ from array destructuring in JavaScript?
i) Object Destructuring
Based on - Property names
Order matters? - ❌ No, order doesn’t matter
Syntax -{ key } = object
Default values - Yes
Renaming - Yes ({ key: newVar })**
ii) Array Destructuring**
Based on - Item positions
Order matters? - ✅ Yes, order matters
Syntax -[value] = array
Default values - Yes
Renaming - Not directly (use assignment after)// Object Destructuring const user = { name: "Jane", age: 28 }; // Extracting by property name const { name, age } = user; console.log(name); // Jane console.log(age); // 28 // Renaming const { name: userName } = user; console.log(userName); // Jane// Array Destructuring const colors = ["red", "green", "blue"]; // Extracting by position const [firstColor, secondColor] = colors; console.log(firstColor); // red console.log(secondColor); // green // Skipping elements const [, , thirdColor] = colors; console.log(thirdColor); // blueUse object destructuring when dealing with objects with named properties, like API responses, config objects, etc.
Use array destructuring when working with ordered collections, like lists, tuples, coordinates, etc.What are dynamic imports in JavaScript?
Dynamic imports in JavaScript let you load modules on the fly—only when they are needed—rather than at the top of your file like traditional static imports. They’re useful for code-splitting, lazy loading, and improving performance.
async function loadModule() { try { const module = await import('./myModule.js'); module.default(); // assuming it's a default export } catch (err) { console.error('Error loading module:', err); } }What is the use of nullish coalescing operator (??) in Javascript?
The nullish coalescing operator (
??) in JavaScript is used to provide a default value when the left-hand side is eithernullorundefined.let userInput = null; let name = userInput ?? "Guest"; console.log(name); // "Guest"If
userInputwere""(an empty string),0, orfalse, nullish coalescing operator would not replace it.What is the use of optional chaining operator (?.) in Javascript?
The optional chaining operator (?.) in JavaScript is used to safely access deeply nested object properties without having to check if each intermediate property exists.
If any part before the?.isnullorundefined, the entire expression returnsundefinedinstead of throwing an error.
Why we use it - To avoid "Cannot read property of undefined" errors when accessing nested values.const user = { name: "John", address: { city: "New York" } }; console.log(user.address?.city); // "New York" console.log(user.profile?.email); // undefined (no error!)What is the event loop in JavaScript, and how does it work?
The event loop is the heart of JavaScript's concurrency model. It’s what allows JavaScript (a single-threaded language) to handle asynchronous operations like timers, network requests, and UI events without blocking the main thread.
How the Event Loop Works -
Call Stack: Executes functions one at a time (LIFO - last in, first out).
Web APIs (Browser or Node.js APIs): Handle things likesetTimeout,fetch, or DOM events.
Callback / Task Queue (or Message Queue): Stores async callbacks until the stack is free.
Event Loop: Monitors the call stack and task queue. When the stack is empty, it pushes the next task from the queue into the stack.What is the difference between shallow copy and deep copy in JavaScript, Explain with example?
i) Shallow Copy - Copies only one level of the object. Nested objects still reference the original.
ii) Deep Copy - Recursively copies all levels, creating completely independent clones.// Shallow Copy const original = { name: "Alice", address: { city: "Wonderland" } }; // Create shallow copy const shallowCopy = { ...original }; // Modify nested property shallowCopy.address.city = "New York"; console.log(original.address.city); // "New York" 😱 (original changed!)Even though we used the spread operator
{ ...original }, it only made a shallow copy—addressis still shared.// Deep Copy const original = { name: "Alice", address: { city: "Wonderland" } }; // Create deep copy using JSON const deepCopy = JSON.parse(JSON.stringify(original)); // Modify nested property deepCopy.address.city = "New York"; console.log(original.address.city); // "Wonderland" ✅ (original untouched)Now the two objects are completely separate.
Shallow copy is fine for simple or flat structures. Deep copy is safer for nested structures, especially when immutability matters (e.g., in state management like React).
Common Ways to Copy -i)
Object.assign({}, obj)
Type - Shallow
Notes - Only top-level copy
ii){ ...obj }
Type - Shallow
Notes - Spread syntax, shallow onlyiii)
JSON.parse(JSON.stringify(obj))
Type - Deep
Notes - Doesn’t handle functions,undefined, or circular refs
iv)structuredClone(obj)
Type - Deep
Notes - Handles most cases, including Date, Map, Set, etc (modern browsers)What is the difference between call(), apply(), and bind() in JavaScript, Explain with example?
call(),apply(), andbind()are Function methods in JavaScript that let you control thethiscontext when invoking or preparing to invoke a function. They're super useful when borrowing functions or working with dynamic context.const person = { fullName: function(city, country) { return `${this.firstName} ${this.lastName} from ${city}, ${country}`; } }; const user = { firstName: "Alice", lastName: "Johnson" }; const result = person.fullName.call(user, "New York", "USA"); console.log(result); // "Alice Johnson from New York, USA" const result = person.fullName.apply(user, ["Paris", "France"]); console.log(result); // "Alice Johnson from Paris, France" const boundFunc = person.fullName.bind(user, "London", "UK"); console.log(boundFunc()); // "Alice Johnson from London, UK"Key Differences -
i) call()
Invokes function? - Immediately
Passes arguments - Individually (arg1, arg2)
Changesthis? - YES
ii) apply()
Invokes function? - Immediately
Passes arguments - As an array ([arg1, arg2])
Changesthis? - YES
iii) bind()
Invokes function? - Later (returns new function)
Passes arguments - Individually (arg1, arg2)
Changesthis? - YESWhat is the difference between map(), filter(), and reduce() in Javascript, Explain with example?
map(),filter(), andreduce()are array methods in JavaScript that help you transform, select, or combine data in arrays in a clean, functional way.
i) map() - Transform elements
Purpose - Transforms each element
Returns - New array
Input - All items
ii) filter() - Select elements that pass a condition
Purpose - Filters elements based on condition
Returns - New array
Input - Some itemsiii) reduce() - Combine all elements into a single result
Purpose - Reduces array to a single value
Returns - Anything (value)
Input - All itemsconst numbers = [1, 2, 3, 4, 5]; const doubled = numbers.map(num => num * 2); console.log(doubled); // [2, 4, 6, 8, 10] const evens = numbers.filter(num => num % 2 === 0); console.log(evens); // [2, 4] const sum = numbers.reduce((acc, curr) => acc + curr, 0); console.log(sum); // 15What is the difference between some() and every() in Javascript, Explain with example?
i) some()
What it checks - At least one element passes
Returns - true/false
Stops when - It finds the first match
Use this when you want to - Check if any item satisfies a condition
ii) every()What it checks - All elements must pass
Returns - true/false
Stops when - It finds the first failure
Use this when you want to - Check if all items satisfy a conditionconst users = [ { name: "Alice", isOnline: true }, { name: "Bob", isOnline: false }, { name: "Charlie", isOnline: true } ]; // ✅ Check if *some* users are online const someoneOnline = users.some(user => user.isOnline); console.log(someoneOnline); // true // ✅ Check if *all* users are online const everyoneOnline = users.every(user => user.isOnline); console.log(everyoneOnline); // falseExplain the concept of prototypes and prototype chain in JavaScript.
In JavaScript, prototypes and the prototype chain are core concepts that allow objects to inherit properties and methods from other objects. This is what makes JavaScript's object-oriented system unique and dynamic.
Every JavaScript object has a prototype—a reference to another object. This prototype object can have properties and methods that are inherited by the original object.
Prototype is essentially a blueprint for creating objects. If an object does not have a property or method that you're trying to access, JavaScript will check its prototype for that property or method.
Prototype Chain -
i) The prototype chain is the mechanism that allows JavaScript objects to inherit from other objects. It’s a chain of objects linked through their prototypes.
ii) Every object has a hidden internal property called[[Prototype]], which points to another object (its prototype).
iii) If the property or method isn’t found on the current object, JavaScript looks up the chain of prototypes to find it.
iv) The chain ends atnull, which is the prototype of theObjectprototype.// Creating a constructor function for a person function Person(name, age) { this.name = name; this.age = age; } // Adding a method to the prototype of Person Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); }; // Creating a new object from Person const alice = new Person("Alice", 30); // Calling the inherited method alice.sayHello(); // "Hello, my name is Alice" // Inspecting the prototype chain console.log(alice.__proto__ === Person.prototype); // true console.log(Person.prototype.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__); // nullWhat is the purpose of Object.freeze() and Object.seal()?
Object.freeze()andObject.seal()are both methods in JavaScript that control how objects can be changed—but they work at different levels of restriction.
i) Object.freeze()
Purpose - Make an object completely immutable.
What it does - Prevents adding, removing, or changing any properties. Makes existing properties non-writable and non-configurable.
Usefreeze()when you want to completely lock an object so no one can change anything about it.const user = { name: "Alice", age: 25 }; Object.freeze(user); user.age = 30; // ❌ Fails silently (in strict mode: TypeError) user.city = "Paris"; // ❌ Fails silently delete user.name; // ❌ Fails silently console.log(user); // { name: "Alice", age: 25 }ii) Object.seal()
Purpose - Make an object non-extensible but still editable
What it does - Prevents adding or deleting properties. Allows changing existing property values. Properties become non-configurable (you can't reconfigure or delete them), but still writable.
Useseal()when you want to lock down the shape of an object but still allow value updates.const settings = { theme: "dark", fontSize: 14 }; Object.seal(settings); settings.theme = "light"; // ✅ Allowed settings.newProp = true; // ❌ Not allowed delete settings.fontSize; // ❌ Not allowed console.log(settings); // { theme: "light", fontSize: 14 }What are WeakMap and WeakSet in JavaScript?
WeakMapandWeakSetare special versions ofMapandSetin JavaScript, with one big difference: they allow "weak references" to objects, which means they don't prevent garbage collection.
InWeakMapandWeakSet, the references to the keys (or values) do not stop them from being garbage collected if there are no other references to those objects.i) WeakMap
Stores key-value pairs.
Keys must be objects (not primitives).
Keys are held weakly (garbage collectible).
Not iterable (can’t loop over it).
Methods:.set(),.get(),.has(),.delete()const weakMap = new WeakMap(); let obj = { name: "Alice" }; weakMap.set(obj, "some metadata"); console.log(weakMap.get(obj)); // "some metadata" obj = null; // Now the key object is eligible for garbage collection // weakMap will automatically remove the entry when GC happensii) WeakSet
Stores objects only (no primitives).Values are held weakly.
Not iterable (no
for...of,.size, etc.).Methods:
.add(),.has(),.delete()const weakSet = new WeakSet(); let user = { name: "Bob" }; weakSet.add(user); console.log(weakSet.has(user)); // true user = null; // Now object can be garbage collected // weakSet will automatically remove the objectWhat is the difference between localStorage and sessionStorage?
BothlocalStorageandsessionStorageare part of the Web Storage API, used for storing data in the browser. But they differ in scope, lifetime, and usage.
i) localStorage
Lifetime - Persistent (stays after page reload or browser close)
Scope - Shared across all tabs/windows of the same origin
Storage limit - ~5–10MB
API syntax - Same (setItem(),getItem(), etc.)
Auto-expiry - ❌ No
ii) sessionStorage
Lifetime - Temporary (cleared when tab is closed)
Scope - Unique to a single tab/session
Storage limit - ~5–10MB
API syntax - Same
Auto-expiry - ✅ Yes (on tab close)// Save to localStorage localStorage.setItem("username", "Alice"); // Get from localStorage const user = localStorage.getItem("username"); console.log(user); // "Alice" // Data stays even after page refresh or browser close// Save to sessionStorage sessionStorage.setItem("cart", JSON.stringify(["apple", "banana"])); // Get from sessionStorage const cart = JSON.parse(sessionStorage.getItem("cart")); console.log(cart); // ["apple", "banana"] // Data disappears when tab is closedUse Case Summary -
Remember login status or theme preferences - localStorage
Store temporary form data while filling - sessionStorage
Maintain state only during a specific tab session - sessionStorageHow do localStorage and cookies differ?
localStorage and cookies are both used for storing data in the browser, but they have different purposes, storage limits, behavior, and accessibility.
i) localStorage
Storage size - ~5–10 MB
Expires - Stays until manually cleared
Accessed by - JavaScript only
Scope - Domain + protocol
Use cases - Storing large data client-side (e.g. theme, token)
Performance - Fast, not sent with requests
Security - No automatic security layer
ii) cookies
Storage size - ~4 KB (very limited)
Expires - Can be set to expire at a specific time
Accessed by - JavaScript and sent with every HTTP request
Scope - Domain + path + protocol
Use cases - Server communication, session management
Performance - Slower, included in every HTTP request
Security -Can be HttpOnly and Secure// Store data localStorage.setItem("theme", "dark"); // Retrieve data const theme = localStorage.getItem("theme");Stored only in the browser.
Not sent to the server automatically.
// JavaScript way (client-side) document.cookie = "user=Alice; expires=Fri, 31 Dec 2025 23:59:59 GMT; path=/";Stored in the browser and sent to the server on each HTTP request
Useful for authentication, session IDs, and server-side reading
Use Case Summary -
Store a user’s theme, preferences, or local data - localStorage
Track logged-in sessions across pages and with the server - Cookies
Store large JSON objects on the client - localStorage
Make data available to both browser and server - CookiesWhat is the DOM in JavaScript?
The DOM (Document Object Model) is a programming interface that represents the structure of a web page in a way that JavaScript can interact with it.
The DOM is a tree-like structure where each element, attribute, and piece of text in an HTML document is represented as a node.
It allows JavaScript to read, modify, and react to HTML content and structure dynamically.
When the browser loads a webpage -It parses the HTML.
It builds a DOM tree that represents all the elements.
JavaScript can then access and manipulate this tree.
<!DOCTYPE html> <html> <body> <h1 id="title">Hello World</h1> <p class="message">Welcome!</p> </body> </html>// Access element by ID const heading = document.getElementById("title"); heading.textContent = "Hello JavaScript!"; // Access element by class const message = document.querySelector(".message"); message.style.color = "blue";Common DOM Methods -
getElementById(id) - Finds an element by ID
getElementsByClassName(class) - Finds elements by class (HTMLCollection)
querySelector(selector) - Finds the first element matching CSS selector
querySelectorAll(selector) - Finds all elements matching CSS selector
createElement(tag) - Creates a new element node// getElementById(id) const title = document.getElementById("main-title"); // getElementsByClassName(class) const items = document.getElementsByClassName("menu-item"); // querySelector(selector) const divs = document.getElementsByTagName("div"); // querySelectorAll(selector) const heading = document.querySelector("h1"); const input = document.querySelector("#search-box"); const button = document.querySelector(".btn.primary"); // querySelectorAll(selector) const buttons = document.querySelectorAll(".btn"); buttons.forEach(btn => btn.style.color = "red");Why is the DOM important? -
Update content dynamicallyChange styles
Handle events like clicks or keyboard input
Create, move, or delete elements
document.querySelector("#submitBtn").addEventListener("click", () => { const input = document.querySelector("#nameInput").value; document.querySelector("#greeting").textContent = `Hello, ${input}!`; });What is the BOM (Browser Object Model)?
The BOM (Browser Object Model) refers to everything JavaScript can interact with outside the webpage content itself — it's how JavaScript talks to the browser.
The BOM is a collection of objects provided by the browser that allows JavaScript to:Interact with the browser window
Control the URL and navigation
Work with popups, alerts, and timers
Access browser history, screen, and more
BOM vs DOM
Purpose - DOM interacts with webpage content, BOM interacts with browser features
Example - DOMdocument.getElementById(), BOMwindow.alert(),location.href
Defined by - DOM W3C/WHATWG, BOM Browser vendors (not standardized)Explain the fetch API?
The Fetch API is a modern way in JavaScript to make HTTP requests (likeGET,POST, etc.) to servers — and it replaces the olderXMLHttpRequestmethod with a cleaner, promise-based approach.
Fetch API - Built into modern browsers. Returns a Promise. Used to fetch data from a server (like an API). Works withasync/awaitor.then()chaining.// GET request fetch("https://jsonplaceholder.typicode.com/posts/1") .then(res => res.json()) // parse JSON from the response .then(data => console.log(data)) .catch(err => console.error("Fetch error:", err));// POST request fetch("https://jsonplaceholder.typicode.com/posts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: "Hello", body: "This is a new post", userId: 1 }) }) .then(res => res.json()) .then(data => console.log(data));fetchdoesn't reject on HTTP errors like 404 or 500 — you need to checkresponse.okmanually.Explain the AXIOS?
Axios is a popular JavaScript library for making HTTP requests — just like thefetchAPI, but with more features out of the box.
What is Axios -
A promise-based HTTP client for the browser and Node.js.Built on top of XMLHttpRequest.
Supports:
i) Request and response interceptors
ii) Automatic JSON transformation
iii) Timeouts, cancellation, and more
iv) Works seamlessly with
async/await// using Promise axios.get(url) .then(response => console.log(response.data)) .catch(error => console.error(error));// using Async/Await const response = await axios.get(url); console.log(response.data);axios.get("https://jsonplaceholder.typicode.com/posts/1") .then(res => { console.log(res.data); });axios.post("https://jsonplaceholder.typicode.com/posts", { title: "Hello", body: "This is a new post", userId: 1 }) .then(res => console.log(res.data)) .catch(err => console.error(err));Installing Axios -
// If you're using Node.js or bundlers like Webpack npm install axios // via CDN for front-end <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>What is difference between fetch and Axios?
i) Axios automatically transforms JSON, fetch requires res.json()
ii) Axios does better error handling via HTTP errors throw but in fetch API you need manual check for.ok
iii) Axios has request & response interceptors but fetch API does not have it.iv) Axios can works in Node.js but fetch API can work only in browsers.
What is JWT (JSON Web Token) in Javascript, and how is it used for securing APIs?
JWT (JSON Web Token) is a compact, URL-safe way to represent claims (like user identity or permissions) that can be verified and trusted. It's commonly used to secure APIs and manage authentication in modern web applications.
A JWT is a string with three parts, separated by dots (.)
header.payload.signature
Parts of a JWT -
i) Header: Metadata about the token{ "alg": "HS256", "typ": "JWT" }ii) Payload: Contains the actual data (user info, roles, etc.)
{ "userId": 123, "email": "joe@gmail.com" }iii) Signature: Ensures the token hasn’t been tampered with (generated using a secret key)
How JWT Works for Securing APIs -
i) Login: User logs in with credentials.ii) Server validates credentials and generates a JWT (with secret key).
iii) Client stores JWT (usually in
localStorageorsessionStorage).iv) For future API calls, the client sends the JWT in the
Authorizationheader:Authorization: Bearer <token>JWT Usage Example in JavaScript -
// Backend (Node.js using jsonwebtoken) const jwt = require("jsonwebtoken"); const token = jwt.sign({ userId: 123 }, "your-secret-key", { expiresIn: "1h" }); console.log(token);// Frontend (sending token with Axios) axios.get("/api/protected", { headers: { Authorization: `Bearer ${yourToken}` } });Benefits of Using JWT -
i) Stateless: No need for server-side sessions.
ii) Secure: Signature verifies data integrity.
iii) Scalable: Ideal for microservices and APIs.
iv) Portable: Can be passed in HTTP headers, cookies, etc.
JWT Security Tips -
i) Always use HTTPS.ii) Store tokens safely (e.g., not in localStorage for highly sensitive data).
iii) Use short expiration times and refresh tokens.
iv) Validate JWTs on every request to protected resources.
How does token-based authentication works in Javascript, and how is it different from session-based authentication?
Token-Based Authentication -
i) Login: User sends credentials (e.g., username/password) to the server.ii) Server validates the credentials and generates a JWT (JSON Web Token).
iii) The token is sent back to the client (browser or mobile app).
iv) The client stores the token (usually in
localStorageorsessionStorage).v) For each subsequent request, the token is sent in the
AuthorizationheaderAuthorization: Bearer <token>vi) The server verifies the token on each request (no session stored).
vii) If the token is valid, access is granted.Pros -
i) Stateless: No session stored on the server.
ii) Scalable: Ideal for distributed systems, APIs, and mobile apps.
iii) Cross-platform: Easy to use on web, mobile, etc.
Cons -
i) Tokens can be stolen if stored insecurely (like inlocalStorage).ii) Harder to revoke access instantly (e.g., logout everywhere).
Session-Based Authentication -
i) Login: User sends credentials to the server.ii) Server validates the credentials and creates a session (usually with a unique session ID).
iii) The session ID is stored in a cookie and sent to the client.
iv) For each request, the cookie is sent automatically to the server.
v) The server matches the session ID to stored session data (like user info).
vi) If valid, the user is authenticated.
Props -
i) Easier to invalidate or revoke sessions.ii) Safer in trusted environments (especially with HTTP-only cookies).
Cons -
i) Server must store session data (not stateless).ii) Harder to scale across multiple servers without shared session storage.
iii) CSRF attacks can be a concern if not protected properly.
// Token-Based // Storing token localStorage.setItem("token", receivedToken); // Sending token with request fetch("/api/user", { headers: { Authorization: `Bearer ${localStorage.getItem("token")}` } });// Session Based - // Server sets cookie with session ID Set-Cookie: sessionId=abc123; HttpOnly // Client automatically sends cookie on each requestWhat is OAuth in Javascript, and how does it secure API access?
OAuth (Open Authorization) is a protocol that allows a third-party application (like your JavaScript app) to access user data from another service (like Google, GitHub, Facebook) — without sharing the user's credentials.
OAuth is for authorization, not authentication (though it's often used for "Login with X").It allows safe, delegated access to APIs using access tokens, not user passwords.
It's a standard way to secure third-party API access in modern apps.
Common Terms -
i) Resource Owner - The user who owns the data
ii) Client - The app requesting access (e.g. your frontend app)
iii) Authorization Server - The server that authenticates the user (e.g. Google login)
iv) Resource Server - The API you want to access (e.g. GitHub API)
v) Access Token - A token used to access protected resourcesHow OAuth Works (Simplified Flow) -
i) User clicks “Login with Google” on your site.ii) Your app redirects the user to Google’s auth server with a request.
iii) The user logs in and consents to share data.
iv) Google redirects back to your app with an authorization code.
v) Your app exchanges that code for an access token (and optionally a refresh token).
vi) Your app uses the access token to call Google APIs on behalf of the user.
How OAuth Secures API Access -i) No passwords are shared with your app.
ii) Access is granted using tokens, not credentials.
iii) Tokens can be scoped (e.g., only read email, not modify contacts).
iv) Tokens can expire and be revoked by the user or provider.
Example Use in JavaScript (Frontend) -// You typically use OAuth with a redirect to the provider // Redirect user to Google's OAuth 2.0 authorization endpoint window.location.href = `https://accounts.google.com/o/oauth2/v2/auth? client_id=YOUR_CLIENT_ID &redirect_uri=http://localhost:3000/callback &response_type=code &scope=email profile`;// After the user logs in and approves, Google redirects them back to your site with a code http://localhost:3000/callback?code=AUTH_CODE// Then your backend exchanges the code for an access token POST https://oauth2.googleapis.com/token { code: "AUTH_CODE", client_id: "YOUR_CLIENT_ID", client_secret: "YOUR_CLIENT_SECRET", redirect_uri: "http://localhost:3000/callback", grant_type: "authorization_code" }Benefits of OAuth -
i) Secure, no password exposure.
ii) Standardized and widely supported (Google, Facebook, GitHub, etc.).
iii) Easily allows third-party integrations.
iv) Grants limited, revocable access to user data.
What is Cross-Site Scripting (XSS) in JavaScript?
XSS (Cross-Site Scripting) is a security vulnerability that allows an attacker to inject malicious JavaScript code into a website, which then runs in another user’s browser.
This can lead to -Stealing cookies/session tokens
Logging keystrokes
Defacing the page
Redirecting users to malicious sites
<!-- User input --> <p>Welcome, <span id="user-name"></span></p> <script> const userInput = "<script>alert('Hacked!')</script>"; document.getElementById("user-name").innerHTML = userInput; </script>Types of XSS Attacks -
i) Stored XSS
Malicious script is saved on the server (e.g., in a database comment), and shown to users.ii) Reflected XSS
Script is injected into a URL and reflected back in the response.example.com/search?q=<script>alert('XSS')</script>iii) DOM-based XSS
JavaScript on the page dynamically inserts unsafe data into the DOM (client-side).
How to Prevent XSS -
i) Escape Output -Use
textContentinstead ofinnerHTML:document.getElementById("user-name").textContent = userInput;ii) Sanitize Input -
Use libraries like: DOMPurify, Google Caja (legacy)const clean = DOMPurify.sanitize(dirtyHTML);iii) Use CSP (Content Security Policy) -
CSP headers block unsafe inline scripts
Content-Security-Policy: default-src 'self'; script-src 'self'iv) Validate Inputs -
Always validate and sanitize user input on both frontend and backend.
How does Cross-Site Request Forgery (CSRF) work?
CSRF (Cross-Site Request Forgery) is an attack where a malicious website tricks a user's browser into making unwanted requests to a different site (where the user is authenticated), without their knowledge.
CSRF tricks your browser into sending unauthorized requests as you.It abuses the trust a site has in the user (not the other way around).
Use CSRF tokens, SameSite cookies, and re-authentication to stop it.
So if you're logged into a site like
bank.com, a malicious site can try to make your browser send a request as you, without you realizing.
You’re logged intobank.com, which uses cookies to remember you. Then you visitevil.com, and it has this hidden form,<form action="https://bank.com/transfer" method="POST"> <input type="hidden" name="amount" value="1000"> <input type="hidden" name="to" value="attacker_account"> <input type="submit"> </form> <script> document.forms[0].submit(); // auto-submits the form </script>Your browser automatically sends your cookies with the request, and
bank.commay process it as a legitimate transaction if it doesn’t check for CSRF.
What Makes CSRF Dangerous? -i) Relies on the user’s authenticated session
ii) The malicious request appears to come from the user
iii) Can lead to data manipulation, money transfers, settings changes, etc.
How to Prevent CSRF -
i) CSRF Tokens (Anti-CSRF Tokens)Include a random, unique token in every sensitive form or request.
Server generates a token and stores it in the user’s session
Token is included in forms as a hidden input
Server checks the token on each request
<input type="hidden" name="csrfToken" value="RANDOM_TOKEN"> // On server if (req.body.csrfToken !== session.csrfToken) { rejectRequest(); }ii) Use
SameSiteCookiesSet cookies with
SameSite=StrictorLaxto prevent them from being sent with cross-site requestsSet-Cookie: sessionId=abc123; SameSite=Strict; Secure; HttpOnlyiii) Require Re-authentication
For sensitive actions (like transferring money), ask users to enter their password again.
What is SQL Injection, and how can it affect JavaScript applications?
SQL Injection is a major web security threat that developers need to understand, especially when using JavaScript on the backend (like with Node.js + a database).
SQL Injection (SQLi) is a vulnerability where an attacker manipulates input fields to inject malicious SQL code into a database query.
If the input is not properly sanitized, the attacker can: View sensitive data (e.g., passwords, emails),Modify or delete data, Bypass authentication, Drop entire tables.
// Vulnerable Code (Unsafe) const username = req.body.username; const password = req.body.password; const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`; db.query(query, function(err, results) { // ... }); // Now if an attacker enters: // username: admin // password: ' OR '1'='1SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1'How to Prevent SQL Injection in JavaScript Apps -
i) Use Prepared Statements / Parameterized Queries - Instead of embedding variables directly, pass them separatelyconst query = "SELECT * FROM users WHERE username = $1 AND password = $2"; client.query(query, [username, password]);ii) Use ORM Libraries -
ORMs like Sequelize, Prisma, and TypeORM automatically handle parameterization
const user = await User.findOne({ where: { username, password } });iii) Sanitize & Validate Input
Use libraries like:
validator, express-validatorconst { check } = require("express-validator"); app.post("/login", [check("username").isAlphanumeric()], (req, res) => { ... });iv) Least Privilege Access
Never give your database user full admin access. Restrict it to only what's necessary.