Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 7:09:38 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
4
high
97
medium
5
low
MCP Server Information
Findings
This package has a B security grade with a safety score of 55/100, driven primarily by 97 medium-severity issues across resource exhaustion, server configuration, and ANSI escape injection vulnerabilities. While there are no critical findings, the 4 high-severity issues combined with weak readiness indicators and insecure container image configurations suggest it requires hardening before production use. The numerous medium-severity issues, particularly around resource management and server setup, indicate this is suitable only for development or non-critical environments without significant remediation.
Dependencies
python-dotenv (2)
black (1)
langchain-openai (1)
pytest (2)
Scan Details
Want deeper analysis?
Fast scan found 24 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnโt shipped yet.
24 of 24 findings
24 findings
Non-cryptographic random source used for security-sensitive value. random.random/randint, Math.random, and numpy.random are predictable; tokens, session IDs, and passwords generated this way are guessable.
Evidence
| 187 | const emailNumber = Math.floor(Math.random() * 1001); |
| 188 | const salonName = |
| 189 | SALON_NAMES[Math.floor(Math.random() * SALON_NAMES.length)]; |
| 190 | const passwordNumber = Math.floor(Math.random() * 90000) + 10000; |
| 191 | const passwordWords = generate({exactly: 2, minLength: 5, maxLength: 12}); |
| 192 | |
| 193 | await signIn('createprefilledaccount', { |
Remediation
Use the secrets module (Python: secrets.token_urlsafe, secrets.choice), crypto.randomBytes (Node), or crypto.getRandomValues (browser). Reserve random.* for simulations, games, and ML sampling.
Install-time script pipes a remote download directly into a shell. Any `npm install` or `docker build` on this package will execute attacker-controlled code without review. Fetch a pinned artifact, verify a checksum, and invoke it explicitly โ or drop the hook entirely.
Evidence
| 24 | && rm -rf /var/lib/apt/lists/* |
| 25 | |
| 26 | # Install Node.js 20 |
| 27 | RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ |
| 28 | && apt-get install -y nodejs \ |
| 29 | && rm -rf /var/lib/apt/lists/* |
Remediation
Prefer libraries that do not require install-time code execution: - Drop `postinstall`/`preinstall`/`prepare` scripts if the work can happen at runtime or build-time instead. - Ship pre-built native binaries rather than compiling via a custom `cmdclass` or `build_ext` override. - For Dockerfiles: replace `RUN curl โฆ | sh` with a pinned download + checksum verification + explicit `RUN` of a named script. - If the hook is unavoidable, document exactly what it does so downstream reviewers
Install-time script pipes a remote download directly into a shell. Any `npm install` or `docker build` on this package will execute attacker-controlled code without review. Fetch a pinned artifact, verify a checksum, and invoke it explicitly โ or drop the hook entirely.
Evidence
| 18 | && rm -rf /var/lib/apt/lists/* |
| 19 | |
| 20 | # Node.js 20 |
| 21 | RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ |
| 22 | && apt-get install -y nodejs \ |
| 23 | && rm -rf /var/lib/apt/lists/* |
Remediation
Prefer libraries that do not require install-time code execution: - Drop `postinstall`/`preinstall`/`prepare` scripts if the work can happen at runtime or build-time instead. - Ship pre-built native binaries rather than compiling via a custom `cmdclass` or `build_ext` override. - For Dockerfiles: replace `RUN curl โฆ | sh` with a pinned download + checksum verification + explicit `RUN` of a named script. - If the hook is unavoidable, document exactly what it does so downstream reviewers
Install-time script pipes a remote download directly into a shell. Any `npm install` or `docker build` on this package will execute attacker-controlled code without review. Fetch a pinned artifact, verify a checksum, and invoke it explicitly โ or drop the hook entirely.
Evidence
| 18 | && rm -rf /var/lib/apt/lists/* |
| 19 | |
| 20 | # Node.js 20 |
| 21 | RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ |
| 22 | && apt-get install -y nodejs \ |
| 23 | && rm -rf /var/lib/apt/lists/* |
Remediation
Prefer libraries that do not require install-time code execution: - Drop `postinstall`/`preinstall`/`prepare` scripts if the work can happen at runtime or build-time instead. - Ship pre-built native binaries rather than compiling via a custom `cmdclass` or `build_ext` override. - For Dockerfiles: replace `RUN curl โฆ | sh` with a pinned download + checksum verification + explicit `RUN` of a named script. - If the hook is unavoidable, document exactly what it does so downstream reviewers
pytest==7.4.4 has 1 known CVE [MEDIUM]: GHSA-6w46-j5rx-g56g. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
langchain-openai==1.0.2 has 1 known CVE [LOW]: GHSA-r7w7-9xr2-qq2r. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
postcss==8.4.38 has 1 known CVE [MEDIUM]: GHSA-qx2v-qp2m-jg93. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
next==14.2.35 has 5 known CVEs [HIGH]: GHSA-3x4c-7xq6-9pq8, GHSA-9g9p-9gw9-jx7f, GHSA-ggv3-7p47-pfv8 (+2 more). Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
python-dotenv==1.2.1 has 1 known CVE [MEDIUM]: GHSA-mf9w-mj56-hr94. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
pytest==7.4.4 has 1 known CVE [MEDIUM]: GHSA-6w46-j5rx-g56g. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
python-dotenv==1.0.1 has 1 known CVE [MEDIUM]: GHSA-mf9w-mj56-hr94. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
black==24.10.0 has 1 known CVE [HIGH]: GHSA-3936-cmfr-pm3m. Upgrade to a patched version.
Remediation
Upgrade the pinned dependency to a patched version. Check the CVE's advisory URL for the recommended safe release, or use `npm audit fix` / `pip-audit --fix`. If no patched release is available yet, pin to a known-good prior version, vendor the fix, or remove the dependency.
tailwindcss-animate==1.0.7 last released 975 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
pytest-json-report==1.5.0 last released 1506 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
yarn==1.22.22 last released 781 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
pytest-json-report==1.5.0 last released 1506 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
random-words==2.0.1 last released 825 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
micro-cors==0.1.1 last released 2529 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
clsx==2.1.0 last released 737 days ago (>730d) โ possible abandoned package
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 343 | # Always switch back to default content |
| 344 | try: |
| 345 | driver.switch_to.default_content() |
| 346 | test["debug_info"].append("โ Switched back to main document context") |
| 347 | except Exception: |
| 348 | pass |
| 349 | |
| 350 | return test |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 116 | finally: |
| 117 | if driver: |
| 118 | try: |
| 119 | driver.quit() |
| 120 | except Exception: |
| 121 | pass |
| 122 | |
| 123 | # Calculate summary statistics |
| 124 | test_results["total_tests"] = len(test_results["tests"]) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 140 | date = datetime.now() |
| 141 | if date_str: |
| 142 | try: |
| 143 | date = parsedate_to_datetime(date_str) |
| 144 | except Exception: |
| 145 | pass |
| 146 | |
| 147 | body = self._get_body(email_message) |
| 148 | return Email( |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 425 | # Always switch back to default content |
| 426 | try: |
| 427 | driver.switch_to.default_content() |
| 428 | test["debug_info"].append("โ Switched back to main document context") |
| 429 | except Exception: |
| 430 | pass |
| 431 | |
| 432 | return test |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1711 | try: |
| 1712 | stripe.AccountSession.create( |
| 1713 | account=account.id, components={"account_onboarding": {"enabled": True}} |
| 1714 | ) |
| 1715 | except stripe.error.StripeError as e: |
| 1716 | pass |
| 1717 | |
| 1718 | |
| 1719 | def generate_sonar_data(demo_desk=False): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.