Security Review — v1.3
Full operability and security code review of the ipinsights.io application.
Review Date: 19 March 2026 · Version: 1.3
Executive Summary
A comprehensive security and operability review was conducted across all application layers including session management, CSRF protection, Content Security Policy, client-side JavaScript security, input validation, authentication, API security, rate limiting coverage, cache control, and HTTP header hardening. Two issues were identified and remediated as part of the v1.3 release. This review supersedes the v1.2 review dated 24 February 2026.
v1.3 Issues Identified & Remediated
Finding: Several Attack Surface Monitoring (ASM) API endpoints under
/api/v1/asm/ did not enforce authentication checks, allowing unauthenticated
users to access ASM asset, dashboard, exposure, and group data.
Fix: Added Auth::requireAuth() gates to all ASM API endpoints,
ensuring only authenticated users with valid sessions or API keys can access ASM data.
Finding: The CSV file upload functionality for bulk asset import did not adequately validate uploaded file content, potentially allowing malformed or malicious data to be processed.
Fix: Hardened CSV upload validation with stricter input sanitisation, file type verification, and content validation before processing imported records.
Previously Remediated Issues (v1.2)
The following issues were identified and fixed in the v1.2 review (24 February 2026):
| Severity | Issue | Status |
|---|---|---|
| MEDIUM | Missing Rate Limiting on Registration Endpoint | Fixed |
| MEDIUM | Missing Rate Limiting on Support Contact Form | Fixed |
| MEDIUM | Missing Cache-Control Headers on Authenticated Pages |
Fixed |
| LOW | Missing object-src 'none' in Content Security Policy |
Fixed |
| LOW | Hardcoded CSRF Token Name in Country Blocklist Endpoint | Fixed |
| LOW | No Centralised Application Version Constant | Fixed |
| LOW | Outdated User-Agent String in API Client | Fixed |
| LOW | Missing SameSite Attribute on Cookie Destruction Path |
Fixed |
Previously Remediated Issues (v1.1)
The following issues were identified and fixed in the v1.1 review (22 February 2026):
| Severity | Issue | Status |
|---|---|---|
| HIGH | Cross-Site Scripting (XSS) in Admin Alert Function | Fixed |
| MEDIUM | Deprecated X-XSS-Protection header enabled | Fixed |
| MEDIUM | Missing Subresource Integrity on Bootstrap CSS | Fixed |
| MEDIUM | Protocol-relative URL for third-party script | Fixed |
| MEDIUM | Missing IP validation on API lookup endpoint | Fixed |
| LOW | Incorrect escaping context in network map attributes | Fixed |
| LOW | Missing rel="noopener noreferrer" on external link |
Fixed |
| LOW | Missing application version identifier | Fixed |
Previously Remediated Issues (v1.0)
The following issues were identified and fixed in the initial review (21 February 2026):
| Severity | Issue | Status |
|---|---|---|
| HIGH | Intermittent CSRF token validation failures (single-use tokens) | Fixed |
| HIGH | Missing CSRF token in JSON error responses | Fixed |
| MEDIUM | False “Network Error” messages from non-JSON responses | Fixed |
| MEDIUM | Content Security Policy blocking HubSpot scripts | Fixed |
Security Controls Verified
The following security controls were reviewed and confirmed to be correctly implemented:
| Control | Status | Details |
|---|---|---|
| Session Hardening | Pass | Strict mode, HttpOnly, SameSite=Strict, secure cookies in production, periodic session ID regeneration, session expiry enforcement, consistent SameSite on cookie destruction |
| Password Security | Pass | bcrypt with cost factor 12, strong password policy enforced (10+ chars, mixed case, digit, special char), automatic rehashing when cost factor changes |
| SQL Injection Prevention | Pass | All database queries use PDO prepared statements with emulated prepares disabled |
| XSS Prevention | Pass | Server-side output escaping via Security::escape(); client-side DOM-based escaping via textContent and escapeAttr() |
| Rate Limiting | Pass | Redis-backed with database fallback; per-IP for web lookups, login, registration, and support; per-key for API; separate limits for each endpoint |
| Account Lockout | Pass | Account locked after 5 failed login attempts; 15-minute lockout period; failed attempt counter reset on successful login |
| Input Validation | Pass | Server-side IP and email validation using filter_var() at both controller and service layers; client-side pre-validation for UX |
| HTTP Security Headers | Pass | X-Content-Type-Options, X-Frame-Options DENY, X-XSS-Protection: 0, Referrer-Policy, Permissions-Policy, HSTS in production, CSP with restricted directives including object-src 'none' |
| Cache Control | Pass | Authenticated pages serve Cache-Control: no-store to prevent caching of sensitive data such as API keys and user lists |
| API Key Security | Pass | 48-character cryptographically random keys; key rotation support with immediate invalidation of old keys |
| Database Security | Pass | Strict SQL mode, UTF-8 with proper collation, credentials loaded from environment variables, singleton pattern prevents connection leaks |
| Subresource Integrity | Pass | SRI hashes present on Bootstrap CSS and JS CDN resources |
| Web Application Firewall | Pass | FOaaS attack detector inspects all requests for injection, traversal, and fuzzing patterns; automatic IP banning after repeated offences |
| Command Injection Prevention | Pass | shell_exec calls for WHOIS and reverse DNS are protected by filter_var(FILTER_VALIDATE_IP) and escapeshellarg() at both caller and function level |
| ASM Authorisation | Pass | Four-tier role model (Anonymous, Free, Pro, Admin) with tier-based feature limits; API endpoints enforce API key, module enablement, and Pro tier gates; enforcement via requireAsmAccess() and requirePro() |
| CSV Upload Hardening | Pass | File extension validation, server-side MIME detection via finfo, 2 MB size limit, tier-based row limits, per-row IP/label/tag sanitisation, transactional import with rollback threshold |
| ASM Rate Limiting | Pass | Redis-backed sliding window counters: form submissions 10/min per user, API calls 60/min per key, CSV uploads 5/hour per user, scan triggers 10/hour per user |
| ASM Audit Logging | Pass | Comprehensive audit trail for state-changing operations, failed authentication attempts, and API access events with user, action, IP, and user-agent recorded |
| Data Encryption at Rest | Pass | AES-256-CBC encryption of ASM exposure evidence with per-user key derivation; soft-delete with 30-day retention for GDPR compliance |
Recommendations
- Enable the HTTPS redirect in
.htaccessfor production deployments to ensure all traffic is encrypted. - Add a Subresource Integrity hash to the Font Awesome CSS CDN link once the hash can be verified from the official source.
- Add automated security testing (e.g. PHPUnit with security-focused test cases) to the development workflow.
- Implement Content-Security-Policy reporting (
report-uriorreport-to) to monitor CSP violations in production. - Consider adding a
Permissions-Policydirective for additional browser features as they become available. - Review and rotate all API keys and database credentials periodically as part of operational security procedures.