Skip to content

Releases: E-Conners-Lab/PyStarter

PyStarter v1.0.8 — local security update

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 27 Sep 17:00
ace6243

Local security update

PyStarter 1.0.8 is intended for a single learner running trusted Python locally. Do not expose it to the internet or use it to execute strangers' code.

  • Fixes CSRF protection, authentication limits, refresh/logout/password-reset revocation and password handling.
  • Fixes draft-content and hidden-test-answer exposure.
  • Bounds execution output and process lifetimes, with Linux resource-limit tests.
  • Updates pinned dependencies and uses a smaller Alpine backend without high/critical image findings or exclusions.
  • Bundles the editor locally, creates separate random installation credentials and limits the database application role.
  • Corrects LICENSE to MIT.

The signed release commit is ace6243658cb16b54674ee267a5870cf597e65c2; its source tree exactly matches the tested candidate. Verification: all ten GitHub checks pass; 106 Linux backend tests and 99 browser tests pass; backend coverage is 90%; all four runtime image scans pass the high/critical gate. This is a dated review, not a guarantee against every vulnerability.

Download and run

This is a source release, not a prebuilt-image runner bundle. Download pystarter-v1.0.8-source.zip, extract it, and install Docker Desktop with Linux containers (or Docker Engine + Compose v2).

On macOS/Linux, from the extracted PyStarter-1.0.8 folder:

./init.sh
docker compose up --build -d

On Windows PowerShell:

powershell -ExecutionPolicy Bypass -File .\init.ps1
docker compose up --build -d

Open http://localhost:8080. The initial build requires internet access. AI is optional and needs your own provider configuration; do not submit secrets or confidential code. No hosted service is included. See README.md and SECURITY.md before running code.

Existing installations: back up first and follow the PostgreSQL role migration in CONTRIBUTING.md. Do not delete your database volume or replace existing database passwords to resolve an upgrade error.

The old 1.0.7 prebuilt images and runner ZIP do not contain these changes. No new prebuilt registry images are included with this source release.

The repository owner approved a one-time independent-review exception for this release. Required checks and signed commits stayed enforced, and the independent-review requirement was restored immediately after merging.

PyStarter v1.0.7 — security hardening (please upgrade)

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 27 Sep 15:55

A security review of 1.0.6 found real problems in how student code was executed. Upgrade if you are running any earlier version, and read SECURITY.md.

What was wrong in 1.0.6 and earlier

  • Student code ran inside the Django process. The Python restrictions can be escaped — submitted code reaches real builtins through ordinary object attributes — and in-process that meant an escape reached the application database connection, the Anthropic API key, the Django secret key, and Django internals.
  • The execution deadline did not stop anything. A 1-second limit returned a timeout status only after the code ran to completion (measured: 9.2s). An infinite loop occupied a worker.
  • The container ran as root, so an escape inside Docker was root inside the container.
  • The stack published on every network interface with TLS, secure cookies, and HSTS off.
  • Tokens lived in browser-readable storage and logout never revoked them server-side.
  • Password validators were configured but never invoked — password1 was an acceptable password.
  • AI critique was ungated and puts the exercise solution in the prompt, so it could be steered into revealing answers for exercises the caller had not solved.

Fixed in 1.0.7

Area Change
Execution Separate process, scrubbed env (no keys, no DB password), memory limits, deadline that kills the job
Container Non-root user, uid 10001
Exposure Binds 127.0.0.1 by default; set NGINX_BIND to widen deliberately
Auth httpOnly cookies, refresh token blacklisted on logout, default-deny permissions
Passwords Django validators enforced on registration and reset
AI Critique requires a passing submission by the requesting user

Verified in a clean install: an escaped payload now sees uid 10001 and four environment variables (HOME, LANG, LC_CTYPE, PATH) — no secret key, no database password.

The honest caveat

This is not a hard security boundary. Submitted Python can still escape the language-level restrictions; what changed is what an escape can reach. There is no seccomp profile, user namespace, or network isolation. PyStarter is for local use with people you trust. For untrusted users, put real isolation under the executor (gVisor, Firecracker, nsjail) — see SECURITY.md.

Upgrading

sed -E -i.bak "s/pystarter-(backend|frontend):[0-9.]+/pystarter-\1:1.0.7/" docker-compose.yml
docker compose pull
docker compose up -d

Your progress in the pgdata volume is untouched. If you previously set NGINX_PORT to reach PyStarter from another machine, note the default is now loopback-only — set NGINX_BIND consciously, and read SECURITY.md first. Existing sessions are invalidated by the move to cookie auth; log in again.

Images

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.7 (linux/amd64, linux/arm64)
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.7 (linux/amd64, linux/arm64)
  • :latest now points at 1.0.7

PyStarter v1.0.6 — AI hints actually work on default settings

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 27 Sep 14:56

Fixes the AI features, which did not work on a default install of 1.0.5 or earlier.

What was broken

.env.example tells you to leave ANTHROPIC_MODEL blank for the default model. Docker Compose passes a blank value through as an empty string, and the backend treated that as a real setting instead of falling back — so every AI request went to the Anthropic API with an empty model name, failed, and surfaced as "Sorry, I am having trouble generating a response right now." even with a valid, paid API key.

Hints, code critique, and error explanations were all affected. Everything else — lessons, exercises, the sandbox, XP and belts — worked normally.

Fixed in 1.0.6

  • Blank ANTHROPIC_MODEL now correctly means claude-opus-5. If you worked around this by setting the model explicitly, nothing changes for you.
  • /api/v1/health/ reports the real release version instead of always saying 1.0.0.
  • :latest now tracks the current release again — it had been stuck on 1.0.3 since April.

Upgrading

Your progress lives in the pgdata volume and is untouched:

sed -E -i.bak "s/pystarter-(backend|frontend):[0-9.]+/pystarter-\1:1.0.6/" docker-compose.yml
docker compose pull
docker compose up -d

Or download the bundle below and unzip it into the same directory name, keeping your existing .env.

Images

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.6 (linux/amd64, linux/arm64)
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.6 (linux/amd64, linux/arm64)

PyStarter v1.0.5 — AI model fix, Intel/AMD images

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 12 Sep 17:51

What's new in 1.0.5

AI model fix. Earlier releases defaulted to claude-sonnet-4-20250514, which Anthropic has deprecated. AI hints, code critique, and error explanations now default to claude-opus-5. If you already set an ANTHROPIC_API_KEY, nothing else changes; just upgrade.

Choose your own model. ANTHROPIC_MODEL and ANTHROPIC_BASE_URL are now passed through to the backend container, so you can set ANTHROPIC_MODEL=claude-haiku-4-5 for cheaper hints, or point ANTHROPIC_BASE_URL at a local Ollama or LM Studio server. See .env.example in the bundle.

Intel/AMD support. Images are now published for linux/amd64 as well as linux/arm64. Previous images were arm64-only, so they did not run on most Windows and Linux machines.

Hardening. The AI provider now handles refusal responses and non-text response blocks, and logs full errors server-side while returning a generic message to the browser. SDK dependencies are pinned to their current major versions.

Upgrading from 1.0.x (keeps your progress)

Your accounts and progress live in the pgdata Docker volume, which the upgrade never touches. From the directory where you run PyStarter:

sed -E -i.bak 's/pystarter-(backend|frontend):[0-9.]+/pystarter-\1:1.0.5/' docker-compose.yml
docker compose pull
docker compose up -d

Migrations run automatically on start. Alternatively, download pystarter-v1.0.5-runner.zip, unzip it into the same directory name you used before, copy your existing .env in, and run docker compose pull && docker compose up -d.

Fresh install

Download pystarter-v1.0.5-runner.zip, unzip, run ./init.sh, then docker compose up -d and open http://localhost. See QUICKSTART.md in the bundle.

PyStarter v1.0.4 — one-command setup (init.sh)

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 24 Apr 01:13

PyStarter v1.0.4

Setup-experience release. No image changes — backend and frontend remain at :1.0.3. Only the runner bundle has changed, so upgrading is optional.

What's new

  • init.sh setup script. Run it once from the unzipped bundle and it:
    • Auto-generates a secure Django secret key (via openssl or python3).
    • Prompts for your Anthropic API key and makes clear it is optional — press Enter to skip. The app runs fully without it; only the AI hint/critique/explanation features are disabled.
    • Writes a ready-to-use .env with permission 600.
    • Refuses to overwrite an existing .env unless you confirm.
  • QUICKSTART.md rewritten to reference ./init.sh and include a feature-parity table showing which features need the API key.
  • .env.example now documents that ANTHROPIC_API_KEY is optional and points to init.sh as the preferred setup path.

New install flow

unzip pystarter-v1.0.4-runner.zip -d pystarter && cd pystarter
./init.sh          # generates secret, asks for optional API key
docker compose up -d
open http://localhost

Upgrading from v1.0.3

No action needed unless you want the new .env helper. To use it on an existing install:

# From the directory where you previously unzipped v1.0.3
curl -LO https://github.com/E-Conners-Lab/PyStarter/releases/download/v1.0.4/pystarter-v1.0.4-runner.zip
unzip -o pystarter-v1.0.4-runner.zip
# your existing .env is untouched; init.sh is now available if you want to regenerate

Container images (unchanged)

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.3
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.3

PyStarter v1.0.3 — fix module ordering & lock state

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 24 Apr 01:04

PyStarter v1.0.3

ℹ️ Superseded by v1.0.4 — same images, but the new runner bundle ships an init.sh that removes the manual .env editing step and makes clear that the Anthropic API key is optional. Functional parity, better UX.

Original release notes below.


Patch release fixing module ordering and lock state.

  • Backend: ModuleListView now explicitly .order_by("order"). Django annotations were breaking the model's default Meta.ordering.
  • Frontend: Dashboard cards now use module.order for the displayed "Module N" label instead of the array index.

Container images

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.3
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.3

PyStarter v1.0.2 — curriculum auto-seeds on startup

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 24 Apr 00:39

PyStarter v1.0.2

⚠️ Known issue: modules display in random order on the Dashboard and the wrong one shows as unlocked. Upgrade to v1.0.3 for correct module ordering and lock state.

Original release notes below, preserved for archival purposes.


Patch release adding automatic curriculum seeding to the container entrypoint. seed_curriculum runs after migrations on every startup (idempotent — skips if modules exist).

Container images

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.2
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.2

PyStarter v1.0.1 — login fix

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 24 Apr 00:29
a97ac5e

PyStarter v1.0.1

⚠️ Known issue: fresh installs from this release show an empty curriculum until python manage.py seed_curriculum is run manually inside the backend container. Upgrade to v1.0.2 for an auto-seeding install.

Original release notes below, preserved for archival purposes.


Patch release fixing login on plain HTTP (localhost). SECURE_SSL_REDIRECT, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE, and HSTS are now env-toggleable.

Container images

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.1
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.1

PyStarter v1.0.0

Choose a tag to compare

@E-Conners-Lab E-Conners-Lab released this 24 Apr 00:03

PyStarter v1.0.0

⚠️ Known issue: login is broken when this release is run over plain HTTP (e.g. http://localhost). Please upgrade to v1.0.1 for a working out-of-the-box install.

Original release notes below, preserved for archival purposes.


Beginner-friendly Python training platform. Runs locally in Docker with pre-built container images.

Container images

  • ghcr.io/e-conners-lab/pystarter-backend:1.0.0
  • ghcr.io/e-conners-lab/pystarter-frontend:1.0.0
  • postgres:16-alpine
  • nginx:alpine

License

Personal-use, non-commercial. See the `LICENSE` file at the top of this repo.