Security Audit Report
Relevant source files
The following files were used as context for generating this wiki page:This document provides a detailed summary of the security audit conducted on the QR-Tool application. The purpose of the audit was to identify and mitigate potential security risks, ensuring the application is safe for production use. The scope included Software Composition Analysis (SCA), application-level vulnerability checks, and a review of security best practices.
The overall status of the application is Ready for Production, with 0 critical vulnerabilities identified after remediation. The application adheres to a security policy which can be reviewed in the Security Policy.
Sources: SECURITY_AUDIT_REPORT.md, README.md:83-93, SECURITY.md
1. Software Composition Analysis (SCA)
SCA was performed to identify vulnerabilities in third-party dependencies.
Sources: SECURITY_AUDIT_REPORT.md:14-53
1.1. Dependency Vulnerabilities
Initially, two vulnerabilities were found. Both have been resolved by updating the affected packages. The application now has 0 vulnerabilities.
The following diagram illustrates the dependency audit and remediation process.
Sources: SECURITY_AUDIT_REPORT.md:18-42, package.json
The following table details the vulnerabilities that were fixed.
| Package | Severity | Vulnerability | Details | Status |
|---|---|---|---|---|
glob@10.4.5 | High | Command injection via CLI (CWE-78) | A transitive dependency via tailwindcss. Low actual risk as it only affects CLI usage, not library usage. | ✅ Fixed (Updated to glob@10.5.0) |
js-yaml@4.1.0 | Moderate | Prototype pollution in merge (CWE-1321) | A transitive dependency via eslint. Low actual risk as the project does not use YAML for ESLint configuration. | ✅ Fixed (Updated to js-yaml@4.1.1) |
Sources: SECURITY_AUDIT_REPORT.md:23-38
1.2. Outdated Dependencies
Several dependencies have available updates but are not considered critical security risks. Minor version updates were applied, while major version updates for tailwindcss and eslint-plugin-react-hooks were deferred to avoid breaking changes, pending further testing.
Sources: SECURITY_AUDIT_REPORT.md:44-63, package.json:23-24
2. Application Security
The audit covered several key areas of application security, all of which passed inspection.
Sources: SECURITY_AUDIT_REPORT.md:65-132
2.1. Cross-Site Scripting (XSS)
The application is protected against XSS attacks primarily through React's built-in content escaping. The audit confirmed:
- No use of
dangerouslySetInnerHTML. - No use of
eval(). - No direct manipulation of
innerHTML.
Sources: SECURITY_AUDIT_REPORT.md:68-76, src/App.jsx
2.2. Input Validation
The application implements comprehensive validation for all user inputs before they are used to generate QR code content. This is a critical defense against malformed or malicious data.
The diagram below shows the general input validation flow.
The following table summarizes the key validation functions.
| Function | Description | QR Types | Source File |
|---|---|---|---|
isValidURL() | Checks if a string is a structurally valid URL. | URL, vCard | qr-helpers.js:28-37 |
isSafeHttpUrl() | Ensures a URL uses only http: or https:. | URL, vCard | qr-helpers.js:95-104 |
isValidEmail() | Validates email address format using a regex. | Email, vCard | qr-helpers.js:44-48 |
isValidPhone() | Allows digits, spaces, and + - (). | Phone, SMS, vCard | qr-helpers.js:55-59 |
isValidLatLng() | Validates latitude (-90 to 90) and longitude (-180 to 180). | Geo | qr-helpers.js:66-74 |
isValidHex() | Validates 3 or 6-digit hex color codes. | Color Pickers | qr-helpers.js:120-121 |
Sources: src/utils/qr-helpers.js, tests/qr-helpers.test.js:46-91, src/App.jsx:311-336
2.3. File Upload Security
Security measures are in place for the optional logo upload feature.
The file upload process follows these steps:
- File Selection: User selects a file via input or drag-and-drop.
- Size Check: The file size is validated against a 4MB limit.
- Type Check: The file's MIME type is checked against a whitelist (
PNG,JPG,WebP,SVG). - URL Creation: If valid, a
blob:URL is created for the image. - Cleanup: The
blob:URL is revoked when the component unmounts or a new logo is chosen to prevent memory leaks.
2.4. Content Security Policy (CSP)
A strict Content Security Policy is defined in the public/_headers file, which is automatically applied by hosting providers like Netlify or Vercel. This policy mitigates risks like 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=()
default-src 'self': Restricts all resources to the same origin.img-src 'self' blob: data:: Allows images from the origin, blob URLs (for uploaded logos), and data URIs (for exported QR codes).style-src 'self' 'unsafe-inline': Allows stylesheets from the origin and inline styles.'unsafe-inline'is required for theqrcode.reactlibrary to function correctly but is considered an acceptable low risk due to React's XSS protection.script-src 'self': Only allows scripts from the same origin.
Sources: SECURITY_AUDIT_REPORT.md:104-120, README.md:63-64
2.5. Local Storage Security
The application uses localStorage to persist user UI preferences, such as theme, selected QR type, and color choices.
- No Sensitive Data: The audit confirms that no sensitive information (tokens, passwords, personal data) is stored.
- Error Handling: The
useLocalStoragehook includes atry-catchblock to handle potential storage errors, such as quota limits. - Serialization: Data is safely serialized and deserialized using
JSON.stringifyandJSON.parse.
Sources: SECURITY_AUDIT_REPORT.md:122-132, src/App.jsx:254-270, index.html:8-14
3. Conclusion
The security audit concludes that the QR-Tool application is ready for production. All identified dependency vulnerabilities have been remediated, and robust application-level security controls are in place. Key security features include comprehensive input validation, protection against XSS, secure file handling, and a strict Content Security Policy. The use of localStorage is limited to non-sensitive UI preferences, aligning with security best practices.
Future work should include periodic npm audit checks and careful testing before updating major dependencies.