Loading report…
← nittim
[](https://nittim.com)Shippable once the listed conditions are addressed.You can make it live once the listed conditions are handled.Handle the listed conditions, then ship.
This verdict covers the 48% of your repository we read — see what we didn’t read below.This result is based on the 48% of your project’s code we actually read — see what we didn’t read below.Covers 48% of your repo — see what we didn’t read below.
This audit read 220 of your 458 files — the ones most likely to hurt you first. The snapshot was truncated — this audit's size limit was reached.
The scores and findings above cover only those files. The rest of the repository hasn’t been audited yet. The denominator counts every file in the repository — images, generated output, vendored and build directories included.
.github/workflows/stats.yml(Commit & Push step: git push "https://preetkaran20:${TOKEN}@github.com/SasanLabs/VulnerableApp.git" HEAD:master) and .github/workflows/zap-benchmark.yml (Commit benchmark results step: same pattern with ${TOKEN}=secrets.GH_TRAFFIC_TOKEN).docker-compose.prod.ymlVulnerableApp-facade ports '0.0.0.0:80:80' with SPRING_PROFILES_ACTIVE=public on the base; scripts/productionize/startup_script.sh brings this stack up on a cloud host.src/main/java/org/sasanlabs/service/vulnerability/jwt/keys/JWTAlgorithmKMS.javaKEY_STORE_PASSWORD = "changeIt" used to open sasanlabs.p12 (RSA_KEY_ALIAS = "SasanLabs").220 of 458 files were audited. This audit's size or file-count limit was reached, so some source and configuration files were left unread. The denominator counts every file in the repository — images, generated output, vendored and build directories included.
This audit's size limit was reached before it read the whole repository. The verdict and every score on this report were computed from what it did read — read them as evidence about that sample, not a clean bill of health for the rest.
The AI-generated likelihood estimate is based on 48% of repository files (220/458) — read it cautiously. The audited files were selected by priority, but a large portion of the repository was not seen.
This repository is OWASP VulnerableApp — a deliberately and intentionally vulnerable Spring Boot (Java 17) application used as a training target and a benchmark harness for DAST/SAST scanners (ZAP integration, benchmark comparison endpoints). The SQL injection, XSS, command injection, path traversal, LDAP injection, JWT flaws, IDOR, weak crypto, session and password-reset weaknesses in the codebase are the PRODUCT, not defects: they are catalogued, level-gated, annotated, and profile-segregated by design. Accordingly they are NOT graded here as production security failures. The engineering AROUND the vulnerabilities is generally mature: an annotation-driven endpoint-discovery framework, Spring profiles ('public' vs 'unsafe') that keep the RCE-class modules (CommandInjection, PathTraversal, RFI, UnrestrictedFileUpload, benchmark writer, email) off in the production compose profile, admin/application datasource privilege separation, an isolated internal Docker network for the base image, randomized credential generation in the startup script, and a working CI/CD + benchmark automation pipeline. Genuine (unintended) concerns are limited and modest: personal-access-tokens embedded directly in git push URLs inside GitHub Actions, a hardcoded demo keystore password, a few placeholder/empty/commented-out classes, a copy-paste no-op constructor bug, and thin runtime observability. Deterministic secret hits are all test data, seed data, or a PEM-delimiter constant — none are live production credentials. There is little defensible proprietary IP and the project is intentionally public and reusable, so IP exposure is a non-issue. Scored as a real deployable service, it is safe to run for its intended purpose provided it stays network-isolated and the CI token handling is tightened.
src/main/java/org/sasanlabs/service/vulnerability/jwt/bean/JWTUtils.java:65(BEGIN_PRIVATE_KEY_TOKEN = "-----BEGIN PRIVATE KEY-----", a format delimiter); src/main/resources/scripts/Authentication/db/data.sql:6,10 (seed passwords for the deliberately vulnerable auth module); src/test/... PasswordHashingUtilsTest / IDORLoginServiceTest / SessionManagementServiceTest (unit-test fixtures)..github/workflows/onboard_sasanlabs.ymlbuilds a Google Forms prefill URL with the merged PR author's login (entry.1414771947=${username}) and posts it as a PR comment. Application user data (auth_users, idor_users incl. salary/email, password_reset_users) is synthetic seed data generated at startup, not real personal data.src/main/java/org/sasanlabs/service/vulnerability/openRedirect/ClientSideInjection.javaand RefreshHeaderBasedInjection.java are empty class bodies; MetaTagBasedInjection.java is entirely commented out including its @VulnerableAppRestController.src/main/java/org/sasanlabs/controller/VulnerableAppRestController.javaconstructor contains this.port = port; where port is an uninitialized instance field, so it assigns 0 to itself; the field is never used thereafter.benchmarks/semgrep-sast-sample.jsonreferences src/main/java/org/sasanlabs/service/vulnerability/imaginary/Imaginary.java with cwe CWE-9999 'Made Up Vulnerability'..github/workflows/create-release.ymlactions/checkout@v2 is passed 'java-version: 1.8' (checkout ignores that input) while the build toolchain elsewhere targets JDK 17 (.github/workflows/gradle.yml, build.gradle toolchain 17).src/main/java/org/sasanlabs/configuration/VulnerableAppConfiguration.javaruns ResourceDatabasePopulator over hand-listed scripts/*/schema.sql and data.sql; entities (AuthUser, VaultEntity, PasswordResetUser/Token) rely on JPA mapping against an H2 database; no Flyway/Liquibase present in the audited snapshot.src/main/java/org/sasanlabs/benchmark/service/DastBenchmarkStrategy.javaand SastBenchmarkStrategy.java implement multi-axis, taxonomy-tolerant matching (URL + any-of type/CWE/WASC, method-ANY fallback, normalized numeric IDs) against ground truth; ground-truth is fetched over HTTP so it works behind the facade.Weighted blend of 4 dimensions → ~73/100. Dimensions are weighted by importance (Security and Privacy weigh heaviest). Published figures are approximate; nittim's exact weighting and precise scoring are proprietary, while the verdict is computed on exact internal values.4 categories combine into ~73/100. Some categories count for more than others (Security and Privacy count the most). The published numbers are approximate; nittim's exact math is kept private, while the verdict itself is worked out from the exact internal numbers.Weighted blend of 4 dimensions → ~73/100 (Security and Privacy weigh heaviest). Published figures are approximate; nittim's exact weighting is proprietary. The verdict runs on exact internal values.
IP Protection is an independent IP-defensibility lens and is excluded from this blend.IP Protection (checking whether your ideas are exposed) is judged separately and isn’t
part of this combined number.IP Protection is judged separately, excluded from this blend.
Scores are a judgement, not a measurement: a re-audit of the same commit can land a few
points either side of this figure. The evidence underneath it is deterministic — the same
commit always yields the same committed-secret and vulnerable-dependency findings.Scores are a judgment call, not an exact measurement: checking the same saved snapshot of
your code twice can land a few points either side of this number. The evidence underneath
it is not — the same snapshot always turns up the same passwords-in-code and known-security-bug
findings.Scores are a judgment, not a measurement — a re-audit can land a few points either side. The evidence underneath is deterministic: the same commit always yields the same secret and vulnerable-dependency findings.
Each score is the model's overall assessment of the dimensions it covers, across everything it reviewed — not a tally of the findings in this report. Findings are the subset worth acting on, so a score can sit above or below what the listed findings alone would suggest.Each score is the AI's overall judgment of everything it reviewed in that category — not a
count of the problems listed in this report. The listed problems are the ones worth acting
on, so a score can sit above or below what they alone would suggest.Each score is the model's overall assessment across everything it reviewed — not a tally of this report's findings. A score can sit above or below what the findings alone suggest.
Dependency manifests: 1 Maven/Gradle manifest read (declared versions, advisory). Ruby dependencies detected — dependency-CVE scanning does not cover it yet; CVEs there are UNVERIFIED, not absent.
Verdict rationale — Why this verdict — Verdict rationale — Judged as what it is — a mature, actively-maintained OWASP deliberately-vulnerable benchmark application — this repository is fit for its intended production use. Its intentional vulnerabilities are the product and are correctly excluded from the security grade; they are also thoughtfully segregated via Spring 'public'/'unsafe' profiles so the RCE-class modules are off in the production compose profile, and the base container is network-isolated (internal:true). Real, unintended issues are modest: personal-access-tokens embedded in git push URLs in CI (tighten before relying on those workflows), a hardcoded demo keystore password, minor dead/placeholder code and a no-op constructor bug, and thin runtime observability. The deterministic secret hits are all fixtures/constants, not live credentials, and no real end-user PII is processed. Conditions for safe operation: (1) keep any exposed deployment network-isolated with the 'unsafe' profile disabled, and (2) remediate the CI token-in-URL handling. IP protection is high (little defensible proprietary IP; intentionally public), and authorship shows a mixed long-lived human core with likely AI assistance in newer modules — neither affects the production verdict.