Now that we understand HTML structure and CSS styling, we turn to JavaScript โ the programming language that makes web pages interactive. JavaScript is central to web security because it's the primary vector for client-side attacks like Cross-Site Scripting (XSS), DOM manipulation, and client-side logic bypasses. You don't need to become a JavaScript developer, but you need to read and understand it well enough to spot vulnerabilities.
JavaScript executes in the user's browser, not on the server. When the browser encounters a <script> tag, it pauses HTML parsing, downloads (if external) and executes the JavaScript, then continues parsing. This execution environment has access to the DOM, cookies, browser storage, and can make network requests.
<!-- External script -->
<script src="https://cdn.example.com/jquery.min.js"></script>
<!-- Inline script -->
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('Page loaded!');
});
</script>
<!-- Event handler (inline) -->
<button onclick="handleClick()">Click Me</button>โ ๏ธ Loading scripts from external CDNs (like the jQuery example above) creates a trust dependency. If the CDN is compromised, malicious JavaScript runs in your users' browsers with full access to your page's DOM and cookies. Always use Subresource Integrity (SRI) hashes when loading external scripts.
Certain JavaScript APIs are particularly relevant to security. When you encounter these during code review, they should immediately draw your attention:
| API | Purpose | Security Risk |
|---|---|---|
| innerHTML | Sets HTML content of an element | XSS if user input is inserted |
| document.write() | Writes content to the document | XSS if input is not sanitized |
| eval() | Executes a string as code | Arbitrary code execution |
| document.cookie | Reads/writes cookies | Session theft via XSS |
| fetch() / XMLHttpRequest | Makes HTTP requests | CSRF, SSRF, data exfiltration |
| window.location | Controls browser navigation | Open redirect, JavaScript injection |
| localStorage / sessionStorage | Client-side data storage | Sensitive data exposure via XSS |
| WebSocket | Persistent server connection | Real-time data manipulation |
The Same-Origin Policy (SOP) is the browser's most important security mechanism. It restricts how a document or script from one origin can interact with resources from another origin. Two URLs have the same origin only if they share the same scheme, host, and port.
URL: https://www.example.com:443/page
|______| |_____________|___|
scheme host port
Same origin: https://www.example.com:443/other-page โ
Different: http://www.example.com:443/page โ (scheme)
Different: https://api.example.com:443/page โ (host)
Different: https://www.example.com:8080/page โ (port)SOP prevents a malicious site from reading data from your bank's website. However, it's important to understand that SOP doesn't prevent requests from being sent โ it prevents the response from being read. This distinction is critical for understanding CSRF attacks.
๐ก Cross-Origin Resource Sharing (CORS) is a mechanism that relaxes SOP. Servers can send Access-Control-Allow-Origin headers to explicitly permit cross-origin access. Misconfigured CORS policies are a common finding in security assessments.
Let's look at both vulnerable and secure patterns so you can recognize them during assessments:
// โ VULNERABLE: DOM-based XSS
const search = document.location.search;
const params = new URLSearchParams(search);
const query = params.get('q');
document.getElementById('results').innerHTML =
'You searched for: ' + query;
// โ
SAFE: Using textContent instead of DOM elements
document.getElementById('results').textContent =
'You searched for: ' + query;// โ VULNERABLE: eval() with user input
const userFormula = getParameter('formula');
const result = eval(userFormula); // Arbitrary code execution!
// โ
SAFE: Use a proper math parser library
const userFormula = getParameter('formula');
const result = mathParser.evaluate(userFormula);// โ VULNERABLE: Sensitive data in localStorage
localStorage.setItem('authToken', jwtToken);
localStorage.setItem('userSSN', '123-45-6789');
// โ
SAFE: Use httpOnly cookies for tokens, never store PII client-side
// Token is set by server via Set-Cookie header with HttpOnly flag
// SSN is never sent to the client at allModern web applications often use AJAX (Asynchronous JavaScript and XML) or the newer fetch() API to load data without refreshing the page. Single-Page Applications (SPAs) built with frameworks like React, Angular, or Vue.js rely heavily on client-side JavaScript and API calls.
// Typical SPA API call pattern
async function getUserProfile(userId) {
const response = await fetch(`/api/users/${userId}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${getToken()}`,
'Content-Type': 'application/json'
},
credentials: 'include'
});
return response.json();
}SPAs shift the attack surface. Traditional form-based attacks may be less relevant, but API-level vulnerabilities (IDOR, broken authentication, mass assignment) become more prominent. When testing SPAs, focus on the underlying API endpoints using your proxy tool.
Verify exercises to earn โ 130 XP and unlock next lab level.