serialize-javascript XSS Vulnerability

CVE-2019-16769

This demonstrates a Cross-Site Scripting (XSS) vulnerability in serialize-javascript versions prior to 2.1.2.

The vulnerability allows attackers to inject malicious JavaScript code that executes in the victim's browser through improperly escaped HTML entities.

CVSS Score: 7.6 (High)

Vulnerability Type: Cross-Site Scripting (XSS)

Fixed Version: 2.1.2

Current Version: 2.1.1

Demonstration

Enter user data that will be serialized using the vulnerable serialize-javascript library:

Serialized Output

// No data serialized yet

Script Execution Result

Simulating data embedded in script tag:
<
script
>
Serialized output will be rendered here

Vulnerability status: Untested

About This Vulnerability

serialize-javascript is a library used to serialize JavaScript to a superset of JSON that includes regular expressions, dates, and functions.

CVE-2019-16769 occurs because the library does not properly escape HTML entities in regular expression literals when used in certain contexts.

This vulnerability can allow attackers to inject malicious JavaScript code that executes in the browser when the serialized output is embedded directly in HTML or used in script tags.

'); } try { // Serialize the data using the vulnerable version const serialized = serialize(userData); // Display the serialized output document.getElementById('serializedOutput').textContent = serialized; // Render the output (simulating how it would be used in an application) const renderContainer = document.getElementById('renderContainer'); // Clear previous content renderContainer.innerHTML = ''; // Create a header const header = document.createElement('h4'); header.className = 'text-lg font-bold mb-2'; header.textContent = 'User Profile'; renderContainer.appendChild(header); // Create a div for user info const userInfo = document.createElement('div'); userInfo.className = 'mb-4'; userInfo.innerHTML = `

Username: ${userData.username}

Bio: ${userData.bio}

Created: ${userData.createdAt.toLocaleDateString()}

`; renderContainer.appendChild(userInfo); // Create a script element and execute the serialized data // This is where the XSS vulnerability would manifest in real applications const scriptElem = document.createElement('script'); scriptElem.textContent = ` // This is how the data would be used in a real application const userData = ${serialized}; // Display validation rules if they exist if (userData.validation) { const validationInfo = document.createElement('div'); validationInfo.className = 'mt-2 p-2 bg-gray-700 rounded'; validationInfo.innerHTML = 'Validation Rule: ' + userData.validation; document.getElementById('renderContainer').appendChild(validationInfo); } `; renderContainer.appendChild(scriptElem); // If no XSS was triggered, update the status after a short delay setTimeout(() => { if (!window.xssDetected) { const vulnStatus = document.getElementById('vulnStatus'); if (payloadType === 'xss') { vulnStatus.textContent = 'Potential vulnerability not triggered'; vulnStatus.className = 'font-bold text-orange-500'; } else { vulnStatus.textContent = 'No vulnerability detected with safe input'; vulnStatus.className = 'font-bold text-green-500'; } } }, 1000); } catch (error) { document.getElementById('serializedOutput').textContent = `Error: ${error.message}`; document.getElementById('renderContainer').innerHTML = `
Error: ${error.message}
`; } }); });