Security Overview
Relevant source files
The following files were used as context for generating this wiki page:The QR-Tool application is a client-side-only tool built with security as a primary consideration. All data processing occurs within the user's browser, and no data is sent to a backend server. The application has undergone a comprehensive security audit, addressing dependency vulnerabilities, input validation, and protection against common web threats like Cross-Site Scripting (XSS). The security model is designed to be robust for a production environment.
This document outlines the key security measures implemented within the project, from dependency management to runtime data handling. For details on reporting new vulnerabilities, please refer to the Security Policy. A detailed audit report is also available.
Sources: README.md:81-89, SECURITY_AUDIT_REPORT.md:9-12, SECURITY.md:3-4
1. Software Composition Analysis (SCA)
An audit of the project's dependencies was performed to identify and remediate known vulnerabilities. The application now has 0 vulnerabilities in its dependencies.
Sources: SECURITY_AUDIT_REPORT.md:16-19, README.md:82
1.1 Remediated Vulnerabilities
The initial audit identified two vulnerabilities in transitive dependencies, which have since been fixed by updating the affected packages.
| Package | Severity | Vulnerability | Status |
|---|---|---|---|
glob@10.4.5 | High | Command injection via CLI (CWE-78) | ✅ Fixed (Updated to glob@10.5.0) |
js-yaml@4.1.0 | Moderate | Prototype pollution in merge (CWE-1321) | ✅ Fixed (Updated to js-yaml@4.1.1) |
The risk from these vulnerabilities was low, as they affected command-line usage or features not used by this project, but they were patched as a matter of best practice. The current dependency tree is clean, as can be verified by running npm audit.
Sources: SECURITY_AUDIT_REPORT.md:21-38, package.json
2. Application Security Measures
The application incorporates several layers of security to protect users and their data during QR code generation.
2.1 Input Validation
All user-provided data is strictly validated before being encoded into a QR code. This prevents malformed data and reduces the attack surface.
The following diagram illustrates the general validation flow for user input in the App.jsx component.
This diagram shows how user input triggers a validation check within a useEffect hook.
Sources: src/App.jsx:311-334
The validation logic relies on a set of helper functions:
| Function | Description | Source File |
|---|---|---|
isValidURL() | Checks if a string is a valid URL format. | src/utils/qr-helpers.js:34-42 |
isSafeHttpUrl() | Ensures a URL uses only http: or https: protocols. | src/utils/qr-helpers.js:77-86 |
isValidEmail() | Validates email format using a regular expression. | src/utils/qr-helpers.js:49-52 |
isValidPhone() | Checks if a string contains only valid phone characters. | src/utils/qr-helpers.js:59-62 |
isValidLatLng() | Validates latitude (-90 to 90) and longitude (-180 to 180). | src/utils/qr-helpers.js:69-74 |
isValidHex() | Validates if a string is a valid 3 or 6-digit hex color. | src/utils/qr-helpers.js:101-102 |
These functions are tested in tests/qr-helpers.test.js to ensure their correctness.
Sources: src/App.jsx:311-334, src/utils/qr-helpers.js:34-102, tests/qr-helpers.test.js:47-100
2.2 Data Escaping
To ensure the generated QR code content is correctly formatted and to prevent injection issues within the QR data standards (e.g., vCard, Wi-Fi), special characters are escaped.
| QR Type | Escaped Characters | Function |
|---|---|---|
| Wi-Fi | ;, ,, :, \, " | escWiFi() |
| vCard | \, ;, ,, \n | escVCARD() |
The generateQRContent function applies these escaping helpers before constructing the final data string.
// src/App.jsx:58-60
const escWiFi = (s = '') => s.replace(/([;,:\\"])/g, '\\$1');
const escVCARD = (s = '') => s.replace(/([\\;,])/g, '\\$1').replace(/\n/g, '\\n');
Sources: src/App.jsx:58-89, src/App.test.js:17-20
2.3 Cross-Site Scripting (XSS) Prevention
The application is protected from XSS attacks primarily through React's built-in content escaping. All data rendered into the DOM is automatically treated as strings, neutralizing any embedded HTML or scripts. The codebase explicitly avoids dangerous practices:
- No use of
dangerouslySetInnerHTML. - No use of
eval(). - No direct manipulation of
innerHTML.
Sources: SECURITY_AUDIT_REPORT.md:96-104
2.4 File Upload Security
The logo upload feature includes client-side validation to mitigate risks associated with file handling.
The following sequence diagram shows the steps involved when a user uploads a logo.
This process ensures only allowed file types and sizes are processed.
Sources: src/App.jsx:611-635, SECURITY_AUDIT_REPORT.md:120-128
2.5 Content Security Policy (CSP)
A strict Content Security Policy is defined in the public/_headers file, which is intended to be used by deployment platforms like Netlify or Vercel. This policy restricts the sources from which resources can be loaded, reducing the risk of XSS and data injection attacks.
Content-Security-Policy: default-src 'self'; img-src 'self' blob: data:; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self'
Referrer-Policy: strict-origin-when-cross-origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
X-XSS-Protection: 1; mode=block
The style-src 'unsafe-inline' is required by the qrcode.react library for responsive rendering but is considered an acceptable risk due to the application's other security measures.
Sources: SECURITY_AUDIT_REPORT.md:130-143, README.md:60-61
2.6 Local Storage Security
The application uses the browser's Local Storage to persist user UI preferences, such as theme, colors, and selected options.
- No sensitive data is stored: Only UI state is saved.
- Error Handling:
try-catchblocks are used aroundlocalStorageaccess to handle potential exceptions like quota limits. - Data is validated on use: All values retrieved from local storage are validated or used in ways that do not pose a security risk.
// src/App.jsx:260-275
function useLocalStorage(key, initialValue, disabled = false) {
const [val, setVal] = React.useState(() => {
if (disabled) return initialValue;
try {
const v = localStorage.getItem(key);
return v !== null ? JSON.parse(v) : initialValue;
} catch {
return initialValue;
}
});
React.useEffect(() => {
if (disabled) return;
try {
localStorage.setItem(key, JSON.stringify(val));
} catch (error) {
console.warn('Failed to save to localStorage:', error);
}
}, [key, val, disabled]);
return [val, setVal];
}
Sources: src/App.jsx:260-275, SECURITY_AUDIT_REPORT.md:145-156, index.html:8-14
2.7 Export and CORS Handling
When exporting a QR code with a logo, the canvas can become "tainted" if the logo is loaded from a cross-origin source without proper CORS headers. The export functionality in ExportPanel.jsx specifically catches this error and provides a user-friendly message.
Sources: src/components/ExportPanel.jsx:70-76
3. Security Policy and Responsible Disclosure
The project maintains a formal security policy outlined in SECURITY.md.
- Supported Versions: Only the latest major version (currently
1.x.x) receives security patches. - Reporting Vulnerabilities: Security issues must be reported privately by creating a "Security advisory" on GitHub or via the contact email
vophuthinhcm@gmail.com. Public GitHub issues should not be used for vulnerability disclosure. - Responsible Disclosure: Reporters are asked not to disclose details publicly until a patch is available.
- User Guidelines: The policy advises users against embedding plaintext secrets in QR codes and recommends deploying the tool over HTTPS.
Sources: SECURITY.md
Summary
The QR-Tool has been developed with a multi-layered security approach suitable for a client-side application. Key security strengths include zero dependency vulnerabilities, comprehensive input validation, robust XSS protection via React, secure file upload handling, and a strict Content Security Policy. The project's "Ready for Production" status is supported by a clean security audit and a clear policy for handling future security concerns.