Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 7:16:29 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
1
high
42
medium
6
low
MCP Server Information
Findings
This package scores 73/100 with a B grade but carries significant configuration concerns, including 34 server configuration issues and 7 instances of verbose error handling that could expose sensitive information. The one high-severity finding combined with 42 medium-severity issuesโprimarily around server setup and container image securityโsuggests it needs hardening before production use. While there are no critical vulnerabilities, the configuration gaps and information disclosure risks warrant careful review and remediation before deployment.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 49 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.
Showing 1โ30 of 49 findings
49 findings
File mounts an HTTP route that handles MCP `tools/list` (Express / Fastify / FastAPI / Flask) but the route โ and the router it sits behind โ has no auth middleware applied. An anonymous client can enumerate every tool the server exposes, scope the attack surface, and (if `tools/call` shares the route) invoke them. Apply auth at the route or router level: Express `passport.authenticate(...)` / a `requireAuth`-style middleware, FastAPI `Depends(get_current_user)` or `Depends(verify_jwt)`, Flask
Evidence
| 1 | # Copyright (c) 2024- Datalayer, Inc. |
| 2 | # |
| 3 | # BSD 3-Clause License |
| 4 | |
| 5 | """ |
| 6 | Tornado request handlers for the Jupyter MCP Server extension. |
| 7 | |
| 8 | This module provides handlers that bridge between Tornado (Jupyter Server) and |
| 9 | FastMCP, managing the MCP protocol lifecycle and request proxying. |
| 10 | """ |
| 11 | |
| 12 | import json |
| 13 | import logging |
| 14 | from typing import Any |
| 15 | from jupyter_server.base.handlers import JupyterHandler |
| 16 | |
| 17 | from jupyter_mcp_server.jupyter_extension.context import get_server_context |
| 18 | from jupyter_mcp_server.server_con |
Remediation
Apply auth middleware at the route or router level: - Express / Fastify / Koa: `passport.authenticate(...)`, `requireAuth`, `verifyToken`, or an equivalent JWT middleware applied via `router.use(authMw)` or as a per-route handler. - FastAPI: `Depends(get_current_user)`, `OAuth2PasswordBearer`, `HTTPBearer`, or `verify_jwt` dependency. - Flask: `@login_required`, `@auth_required`, `@jwt_required`, or call `verify_jwt_in_request()` in the handler. Mounting MCP behind a s
Service binds to 0.0.0.0 โ all network interfaces. For MCP servers that only need to talk to a single parent process, bind to 127.0.0.1 (or a Unix domain socket) instead.
Evidence
| 292 | if transport == "stdio": |
| 293 | mcp.run(transport="stdio") |
| 294 | elif transport == "streamable-http": |
| 295 | uvicorn.run(mcp.streamable_http_app, host="0.0.0.0", port=port) # noqa: S104 |
| 296 | else: |
| 297 | raise Exception("Transport should be `stdio` or `streamable-http`.") |
Remediation
Bind to 127.0.0.1 for local-only access. If cross-host access is truly required, put the service behind an authenticated reverse proxy rather than exposing it on 0.0.0.0.
Container base image uses the floating :latest tag. This provides no reproducibility โ the image content can change under you, and there is no signature to verify.
Evidence
| 134 | ```dockerfile |
| 135 | # Dockerfile for single-user image |
| 136 | FROM jupyter/minimal-notebook:latest |
| 137 | |
| 138 | RUN pip install "jupyter-mcp-server>=0.15.0" \ |
| 139 | "jupyterlab==4.4.1" \ |
Remediation
Pin the base image by digest (e.g. python@sha256:...) or at minimum an exact semver tag (e.g. python:3.12.4-slim-bookworm). Never use :latest in production Dockerfiles.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 932 | except Exception as e: |
| 933 | logger.error(f"Error executing cell locally: {e}") |
| 934 | return [f"[ERROR: {str(e)}]"] |
| 935 | |
| 936 | |
| 937 | async def get_jupyter_ydoc(serverapp: Any, file_id: str): |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 184 | return JSONResponse({"success": True}) |
| 185 | except Exception as e: |
| 186 | logger.error(f"Failed to connect: {e}") |
| 187 | return JSONResponse({"success": False, "error": str(e)}, status_code=500) |
| 188 | |
| 189 | |
| 190 | @mcp.custom_route("/api/stop", ["DELETE"]) |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 749 | except Exception as e: |
| 750 | logger.error(f"Error executing code locally: {e}") |
| 751 | return [f"[ERROR: {str(e)}]"] |
| 752 | |
| 753 | |
| 754 | async def execute_cell_local( |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 188 | return format_TSV(headers, rows) |
| 189 | |
| 190 | except Exception as e: |
| 191 | return f"Error formatting kernel list: {str(e)}" |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 196 | return JSONResponse({"success": True}) |
| 197 | except Exception as e: |
| 198 | logger.error(f"Error stopping notebook: {e}") |
| 199 | return JSONResponse({"success": False, "error": str(e)}, status_code=500) |
| 200 | |
| 201 | |
| 202 | @mcp.custom_route("/api/healthz", ["GET"]) |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 124 | code=code, kernel_id=kid, metadata={}, |
| 125 | outputs=[], error=e, context=hook_ctx, |
| 126 | ) |
| 127 | return [f"[ERROR: {str(e)}]"] |
| 128 | |
| 129 | async def execute( |
| 130 | self, |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 560 | except Exception as e: |
| 561 | logger.error(f"Error executing via ExecutionStack: {e}", exc_info=True) |
| 562 | return [f"[ERROR: {str(e)}]"] |
| 563 | |
| 564 | |
| 565 | async def execute_code_local( |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 87 | async def _list_files_local( |
| 88 | contents_manager: Any, |
| 89 | path: str = "", |
| 90 | max_depth: int = 1, |
| 91 | current_depth: int = 0 |
| 92 | ) -> List[Dict[str, Any]]: |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 135 | kernel_spec_manager=None, |
| 136 | notebook_manager=None, |
| 137 | # Tool-specific parameters |
| 138 | code: str = None, |
| 139 | timeout: int = 60, |
| 140 | kernel_id: str = None, |
| 141 | ensure_kernel_alive_fn=None, |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 38 | class NotebookContentResponse(BaseModel): |
| 39 | """Response containing notebook content""" |
| 40 | path: str = Field(..., description="Notebook path") |
| 41 | cells: list[dict[str, Any]] = Field(..., description="List of cells") |
| 42 | metadata: dict[str, Any] = Field(default_factory=dict, description="Notebook metadata") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 32 | # Notebook operation models |
| 33 | class NotebookContentRequest(BaseModel): |
| 34 | """Request to retrieve notebook content""" |
| 35 | path: str = Field(..., description="Path to the notebook file") |
| 36 | include_outputs: bool = Field(True, description="Include cell outputs") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 170 | kernel_spec_manager: Optional[Any] = None, |
| 171 | notebook_manager: Optional[Any] = None, |
| 172 | # Tool-specific parameters |
| 173 | path: str = "", |
| 174 | max_depth: int = 1, |
| 175 | start_index: int = 0, |
| 176 | limit: int = 25, |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
Dockerfile never sets a non-root `USER` directive, so the CMD runs as root by default. Any RCE or library-level vulnerability exploited inside this container gets full privileges (MCP Top-10 R3). Add `USER <non-root>` before CMD / ENTRYPOINT in the final stage โ e.g. `USER 1000`, `USER nobody`, or `USER nonroot` on distroless.
Evidence
| 1 | # Copyright (c) 2024- Datalayer, Inc. |
| 2 | # |
| 3 | # BSD 3-Clause License |
| 4 | |
| 5 | FROM python:3.12-slim |
| 6 | |
| 7 | WORKDIR /app |
| 8 | |
| 9 | COPY pyproject.toml LICENSE README.md ./ |
| 10 | COPY jupyter_mcp_server/ jupyter_mcp_server/ |
| 11 | COPY jupyter-config/ jupyter-config/ |
| 12 | |
| 13 | ENV PIP_NO_CACHE_DIR=1 \ |
| 14 | PIP_DEFAULT_TIMEOUT=120 \ |
| 15 | PIP_DISABLE_PIP_VERSION_CHECK=1 |
| 16 | RUN python -m pip install --upgrade pip wheel setuptools && pip --version |
| 17 | |
| 18 | RUN pip install --no-cache-dir -e . && \ |
| 19 | pip uninstall -y pycrdt datalayer_pycrdt && \ |
| 20 | pip install -- |
Remediation
Create and switch to a non-root user before the CMD / ENTRYPOINT: RUN adduser --system --uid 1000 app USER 1000 Or reuse the base image's shipped non-root account (e.g. `USER nobody`, `USER nonroot` on distroless). Multi-stage builds only need the USER directive in the final stage.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 54 | path: dist |
| 55 | |
| 56 | - name: Publish to PyPI |
| 57 | uses: pypa/gh-action-pypi-publish@release/v1 |
| 58 | with: |
| 59 | # No password needed, using OIDC trusted publishing |
| 60 | skip-existing: true |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 20 | steps: |
| 21 | - name: Checkout |
| 22 | uses: actions/checkout@v6 |
| 23 | |
| 24 | - name: Set up Python ${{ matrix.python-version }} |
| 25 | uses: actions/setup-python@v6 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 53 | # steps: |
| 54 | # - uses: actions/checkout@v6 |
| 55 | # - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 |
| 56 | # - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 |
| 57 | |
| 58 | test_lint: |
| 59 | runs-on: ubuntu-latest |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 15 | name: Build Python Package |
| 16 | runs-on: ubuntu-latest |
| 17 | steps: |
| 18 | - uses: actions/checkout@v6 |
| 19 | |
| 20 | - name: Set up Python |
| 21 | uses: actions/setup-python@v6 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 83 | uses: docker/setup-buildx-action@v4 |
| 84 | |
| 85 | - name: Log in to Docker Hub |
| 86 | uses: docker/login-action@v4 |
| 87 | with: |
| 88 | username: ${{ secrets.DOCKERHUB_USERNAME }} |
| 89 | password: ${{ secrets.DOCKERHUB_TOKEN }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 79 | with: |
| 80 | python-version: ${{ matrix.python-version }} |
| 81 | architecture: "x64" |
| 82 | - uses: actions/download-artifact@v8 |
| 83 | with: |
| 84 | name: jupyter_mcp_server-sdist-${{ matrix.python-version }} |
| 85 | - name: Install and Test |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 89 | password: ${{ secrets.DOCKERHUB_TOKEN }} |
| 90 | |
| 91 | - name: Build and push Docker image |
| 92 | uses: docker/build-push-action@v7 |
| 93 | with: |
| 94 | context: . |
| 95 | platforms: linux/amd64,linux/arm64 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 18 | - uses: actions/checkout@v6 |
| 19 | |
| 20 | - name: Set up Python |
| 21 | uses: actions/setup-python@v6 |
| 22 | with: |
| 23 | python-version: '3.10' |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 21 | steps: |
| 22 | - name: Checkout |
| 23 | uses: actions/checkout@v6 |
| 24 | |
| 25 | - name: Set up Python ${{ matrix.python-version }} |
| 26 | uses: actions/setup-python@v6 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 108 | permissions: |
| 109 | contents: write |
| 110 | steps: |
| 111 | - uses: actions/checkout@v6 |
| 112 | with: |
| 113 | fetch-depth: 0 # Fetch complete history for release creation |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 28 | python-version: ${{ matrix.python-version }} |
| 29 | |
| 30 | - name: Base Setup |
| 31 | uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 |
| 32 | |
| 33 | - name: Install the extension |
| 34 | run: | |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 73 | steps: |
| 74 | - name: Checkout |
| 75 | uses: actions/checkout@v6 |
| 76 | - name: Install Python |
| 77 | uses: actions/setup-python@v6 |
| 78 | with: |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 80 | platforms: arm64 |
| 81 | |
| 82 | - name: Set up Docker Buildx |
| 83 | uses: docker/setup-buildx-action@v4 |
| 84 | |
| 85 | - name: Log in to Docker Hub |
| 86 | uses: docker/login-action@v4 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 75 | run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT |
| 76 | |
| 77 | - name: Set up QEMU |
| 78 | uses: docker/setup-qemu-action@v4 |
| 79 | with: |
| 80 | platforms: arm64 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 58 | test_lint: |
| 59 | runs-on: ubuntu-latest |
| 60 | steps: |
| 61 | - uses: actions/checkout@v6 |
| 62 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 |
| 63 | - name: Run Linters |
| 64 | run: | |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 17 | steps: |
| 18 | - name: Checkout |
| 19 | uses: actions/checkout@v6 |
| 20 | with: |
| 21 | token: ${{ secrets.GITHUB_TOKEN }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 48 | id-token: write # Required for OIDC |
| 49 | steps: |
| 50 | - name: Download artifacts |
| 51 | uses: actions/download-artifact@v8 |
| 52 | with: |
| 53 | name: python-package |
| 54 | path: dist |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 52 | # runs-on: ubuntu-latest |
| 53 | # steps: |
| 54 | # - uses: actions/checkout@v6 |
| 55 | # - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 |
| 56 | # - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 |
| 57 | |
| 58 | test_lint: |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 31 | run: python -m build |
| 32 | |
| 33 | - name: Upload artifacts |
| 34 | uses: actions/upload-artifact@v7 |
| 35 | with: |
| 36 | name: python-package |
| 37 | path: dist/* |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 75 | - name: Checkout |
| 76 | uses: actions/checkout@v6 |
| 77 | - name: Install Python |
| 78 | uses: actions/setup-python@v6 |
| 79 | with: |
| 80 | python-version: ${{ matrix.python-version }} |
| 81 | architecture: "x64" |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 51 | # check_links: |
| 52 | # runs-on: ubuntu-latest |
| 53 | # steps: |
| 54 | # - uses: actions/checkout@v6 |
| 55 | # - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 |
| 56 | # - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 42 | pip uninstall -y "jupyter_mcp_server" |
| 43 | rm -rf "jupyter_mcp_server" |
| 44 | |
| 45 | - uses: actions/upload-artifact@v7 |
| 46 | if: startsWith(matrix.os, 'ubuntu') |
| 47 | with: |
| 48 | name: jupyter_mcp_server-sdist-${{ matrix.python-version }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 68 | packages: write # For GHCR |
| 69 | id-token: write # For Docker Hub OIDC (optional) |
| 70 | steps: |
| 71 | - uses: actions/checkout@v6 |
| 72 | |
| 73 | - name: Extract version from tag |
| 74 | id: version |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 59 | runs-on: ubuntu-latest |
| 60 | steps: |
| 61 | - uses: actions/checkout@v6 |
| 62 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 |
| 63 | - name: Run Linters |
| 64 | run: | |
| 65 | bash ./.github/workflows/lint.sh |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 23 | uses: actions/checkout@v6 |
| 24 | |
| 25 | - name: Set up Python ${{ matrix.python-version }} |
| 26 | uses: actions/setup-python@v6 |
| 27 | with: |
| 28 | python-version: ${{ matrix.python-version }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 24 | uses: actions/checkout@v6 |
| 25 | |
| 26 | - name: Set up Python ${{ matrix.python-version }} |
| 27 | uses: actions/setup-python@v6 |
| 28 | with: |
| 29 | python-version: ${{ matrix.python-version }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
Server sets a CORS configuration with wildcard / reflected origin AND credentials enabled. Browsers either reject the combo (literal `*` + credentials) or accept it (reflected `req.headers.origin` + credentials), but in both cases this creates a CSRF amplifier โ any origin can issue authenticated requests to the server with the user's cookies. Fix: enumerate the trusted origins explicitly in the CORS config, or drop credentials and use `Authorization` header bearer tokens (browser-safe under wi
Evidence
| 98 | ) |
| 99 | |
| 100 | # Add CORS middleware |
| 101 | app.add_middleware( |
| 102 | CORSMiddleware, |
| 103 | allow_origins=["*"], # In production, should set specific domains |
| 104 | allow_credentials=True, |
| 105 | allow_methods=["*"], |
| 106 | allow_headers=["*"], |
| 107 | ) |
Remediation
Replace wildcard / reflected origin with an explicit allowlist of trusted origins: cors({ origin: ["https://app.example.com", "https://admin.example.com"], credentials: true, }) Or, if the API genuinely should be accessible from any origin, drop credentials and use bearer tokens in the `Authorization` header instead โ that combo is browser-safe.
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
| 355 | # Get final result |
| 356 | try: |
| 357 | await execution_future |
| 358 | except asyncio.CancelledError: |
| 359 | pass |
| 360 | |
| 361 | return None |
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
| 381 | code=cell_source, kernel_id=kid, metadata={}, |
| 382 | outputs=partial_outputs, error=e, context=hook_ctx, |
| 383 | ) |
| 384 | return partial_outputs |
| 385 | except Exception: |
| 386 | pass |
| 387 | |
| 388 | timeout_result = [f"[TIMEOUT ERROR: Cell execution exceeded {timeout_seconds} seconds and was interrupted]"] |
| 389 | await hooks.fire( |
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
| 972 | try: |
| 973 | yroom = await ywebsocket_server.get_room(room_id) |
| 974 | if yroom and hasattr(yroom, '_document'): |
| 975 | return yroom._document |
| 976 | except Exception: |
| 977 | pass |
| 978 | |
| 979 | except Exception: |
| 980 | # YDoc not available, will fall back to file operations |
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
| 319 | execution_future.cancel() |
| 320 | try: |
| 321 | if hasattr(kernel, 'interrupt'): |
| 322 | kernel.interrupt() |
| 323 | except Exception: |
| 324 | pass |
| 325 | raise asyncio.TimeoutError(f"Cell execution timed out after {timeout_seconds} seconds") |
| 326 | |
| 327 | # Check for new outputs and try to trigger sync |
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
| 128 | try: |
| 129 | from datetime import datetime |
| 130 | dt = datetime.fromisoformat(last_modified.replace('Z', '+00:00')) |
| 131 | last_modified = dt.strftime("%Y-%m-%d %H:%M:%S") |
| 132 | except Exception: |
| 133 | pass |
| 134 | |
| 135 | file_info = { |
| 136 | 'path': item_path, |
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
| 288 | outputs_log.append(f"[TIMEOUT at {elapsed:.1f}s: Cancelling execution]") |
| 289 | try: |
| 290 | kernel.interrupt() |
| 291 | outputs_log.append("[Sent interrupt signal to kernel]") |
| 292 | except Exception: |
| 293 | pass |
| 294 | break |
| 295 | |
| 296 | # Check for new outputs |
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.