VINCI
Vinci VAPT Report.
Non-destructive application-security assessment of the Vinci UAT prototype.
- Assessment date
- 25 July 2026
- Target
- vinci.riskinsights.in
- Release tested
- Hardened release following db2e5aa
- Residual rating
- LOW
All identified findings remediated; independent production testing remains required.
No Critical or High-severity vulnerability was identified within the agreed, non-destructive scope. Authentication uses password, a human challenge and email OTP; OTPs are hashed, expire after ten minutes and permit five attempts. Login and password-reset requests are rate-limited, a new login invalidates the previous session, protected application routes require authentication, and supervisor actions apply maker-checker restrictions.
The hardening release closed all six Medium and five Low findings identified in the initial assessment. The controls include bounded upload processing, structured security events, user-controlled first-use passwords, CSP and Permissions Policy, idle and absolute session limits, hashed dependency locking, production admin removal, no-store authentication responses, protected exception handling, security.txt and a cryptographic human challenge. Independent credentialed testing and cloud-control review are still required before production certification.
Assessment coverage.
Included
- Django application source, routes, forms, models and templates
- Authentication, OTP, password reset and session handling
- Role checks, maker-checker controls and anonymous access
- CSRF, host validation, HTTP methods and security headers
- CSV/XLSX upload handling and outbound API calls
- Dependency and source-code vulnerability scans
- HTTPS redirect, certificate and TLS protocol checks
- Repository secret-pattern review and Django deployment checks
Excluded / limitations
- No denial-of-service, load, phishing or social-engineering test
- No destructive payloads or access to real portfolio data
- No cloud control-plane, employee device or bank-network assessment
- No source-origin port scan behind Cloudflare/Render
- No independent audit of Render, Neon, Resend or Cloudflare
- No mobile application or API client exists in this release
The work followed a risk-based review aligned to NIST SP 800-115 and the OWASP Top 10:2025. A VAPT is evidence from a defined scope and date; it is not a guarantee that no vulnerability exists.
Controls verified.
Remediation register — all items resolved.
The badges below retain each finding’s original risk classification. Every listed recommendation was implemented in the hardened release and is subject to the retest evidence recorded below.
Content Security Policy and Permissions Policy are absent
The live response includes HSTS, frame denial and MIME protection, but no Content-Security-Policy or Permissions-Policy. A restrictive CSP reduces the impact of a future injection defect.
Recommendation: Introduce a tested nonce- or hash-based CSP and a minimal Permissions-Policy; begin in report-only mode.
Upload resource-exhaustion controls are incomplete
Portfolio uploads have a 10 MB compressed-file limit, but XLSX decompression/worksheet complexity is not bounded. Market-data CSV upload has no explicit byte or row limit. An authenticated user could exhaust memory, CPU or database capacity.
Recommendation: Add byte, row, column, decompressed-size and processing-time limits; reject encrypted or malformed workbooks; process large files asynchronously.
Security logging and alerting are not comprehensive
The application records risk runs, but does not maintain a tamper-evident security trail for successful/failed login, OTP failures, password resets, user administration, uploads, methodology changes and authorization failures.
Recommendation: Add structured security events, protected retention, correlation IDs, alert thresholds and supervisor review.
Dependencies are range-pinned without hashes or a lock file
No known vulnerability was found, but deployment may resolve a different package version on a future build, weakening reproducibility and software-supply-chain control.
Recommendation: Maintain a reviewed lock file with exact versions and hashes; run dependency scanning on every change.
Session duration lacks an inactivity timeout
The Django session lifetime is approximately 14 days. Secure cookies and single-session enforcement are present, but there is no short idle timeout appropriate to sensitive bank-risk activity.
Recommendation: Introduce a 15–30 minute idle timeout, an absolute session lifetime and re-authentication for sensitive actions.
Supervisor-created passwords do not force first-use reset
The two bootstrap UAT accounts correctly require email-based password creation. However, the in-app new-user workflow accepts a password chosen by the supervisor and does not set the account’s mandatory-reset flag.
Recommendation: Create all users with an unusable password and require the registered user to establish it through verified email.
Django administration endpoint remains exposed
The standard /admin/ login is internet-reachable, although model permissions still apply.
Recommendation: Disable it for UAT if unused, or restrict it by network and a separate administrator role.
Authentication responses lack explicit no-store caching
Cloudflare currently reports dynamic handling, but login, OTP and password-reset responses do not explicitly instruct every intermediary and browser not to store them.
Recommendation: Add Cache-Control: no-store, private to authentication and sensitive report responses.
Selected exception details are returned to authenticated users
Automatic market-data fetch and risk-run failures include exception text in the user message. A library or infrastructure error could disclose internal detail.
Recommendation: Show a generic reference code to users and retain detailed exceptions only in protected logs.
No coordinated vulnerability-disclosure file
/.well-known/security.txt is absent, so external researchers have no standard reporting channel.
Recommendation: Publish a security.txt file with a monitored contact and disclosure policy before wider exposure.
Human challenge is simple and non-cryptographic
The arithmetic challenge is generated with a general-purpose pseudo-random function. It is only a supplementary anti-automation control; email OTP and throttling remain the substantive controls.
Recommendation: Keep throttling primary and replace the challenge with a stronger accessible anti-bot control if automated abuse emerges.
Recorded results.
| Test | Result | Evidence |
|---|---|---|
| Django deployment check | PASS | No issues under production security settings. |
| Python dependency audit | PASS | 0 known vulnerabilities reported. |
| Bandit static scan | REVIEWED | 0 High findings; URL-open and test-fixture warnings manually assessed. |
| Regression suite | PASS | 17 of 17 automated tests passed before assessment publication. |
| HTTPS and certificate | PASS | Valid certificate for vinci.riskinsights.in; HTTP redirects to HTTPS. |
| TLS protocols | PASS | TLS 1.0/1.1 rejected; TLS 1.2/1.3 accepted. |
| CSRF enforcement | PASS | POST without CSRF token returned HTTP 403. |
| Host validation | PASS | Unrecognised Host returned HTTP 403. |
| Anonymous route access | PASS | Portfolio, upload, market-data, methodology, report and audit routes redirected to login. |
| Unsupported methods | PASS | TRACE/OPTIONS rejected; state-changing unsupported methods rejected. |
| Tracked-source secrets | PASS | No live private key, Resend key or production database credential identified. |
Recommended sequence.
- Before broader UAT: bound all upload processing; add security-event logging; enforce first-use password creation for every new user.
- Before production: deploy CSP/Permissions-Policy, short idle sessions, locked dependencies, protected error handling and restricted administration.
- Before bank approval: commission an independent credentialed penetration test and review cloud configuration, backups, retention, incident response and data-processing agreements.