Skip to content

chore(deps): consolidate dependency updates#263

Merged
DogukanUrker merged 2 commits into
mainfrom
feat/consolidated-dependency-updates
Jun 27, 2026
Merged

chore(deps): consolidate dependency updates#263
DogukanUrker merged 2 commits into
mainfrom
feat/consolidated-dependency-updates

Conversation

@DogukanUrker

@DogukanUrker DogukanUrker commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Consolidated 6 dependabot PRs into a single PR for cleaner update history.

Changes

  • flask: 3.1.2 → 3.1.3
  • ruff: 0.15.0 → 0.15.4
  • python-dotenv: 1.2.1 → 1.2.2
  • filelock: 3.20.3 → 3.25.0
  • markdown2: 2.5.4 → 2.5.5
  • requests: 2.32.5 → 2.33.0

Both pyproject.toml and uv.lock have been updated to reflect these changes.

Summary by CodeRabbit

  • Bug Fixes

    • Redirects after login now stay on local app paths, reducing the risk of unsafe external redirects.
    • Admin-only areas now reject non-admin users sooner, improving access control behavior.
    • Default admin setup now requires a password to be provided, preventing insecure startup defaults.
  • Chores

    • Updated several package versions to exact pinned releases for more consistent installs.

Security Researcher and others added 2 commits May 16, 2026 19:00
- Remove hardcoded SMTP credentials (CWE-798)
- Require DEFAULT_ADMIN_PASSWORD from environment (CWE-1392)
- Fix missing authorization check in admin panel (CWE-862)
- Fix open redirect in login route (CWE-601)

Co-Authored-By: Security Researcher <noreply@anthropic.com>
- flask: 3.1.2 → 3.1.3
- ruff: 0.15.0 → 0.15.4
- python-dotenv: 1.2.1 → 1.2.2
- filelock: 3.20.3 → 3.25.0
- markdown2: 2.5.4 → 2.5.5
- requests: 2.32.5 → 2.33.0

Consolidated from 6 dependabot PRs into single update PR.
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR pins several runtime dependencies, removes hardcoded SMTP and default-admin credentials, sanitizes login redirect targets, and rejects non-admin access to the admin panel before the route continues.

Changes

Application hardening

Layer / File(s) Summary
Startup credential defaults
app/settings.py
SMTP_MAIL and SMTP_PASSWORD now default to empty strings, and DEFAULT_ADMIN_PASSWORD must be set when DEFAULT_ADMIN is enabled or startup raises RuntimeError.
Login redirect validation
app/routes/login.py
urlparse is imported, and the direct parameter is clamped to / when it is missing, external, or not a local path.
Admin access check
app/routes/admin_panel_users.py
Non-admin users are redirected to / and logged immediately after the current user is loaded.
Dependency version pins
app/pyproject.toml
Several runtime dependencies switch from >= constraints to exact == pins, with new exact pins added for ruff, filelock, and requests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I hopped through logs with velvet feet,
And pinned each package nice and neat.
The redirect path stayed snug and true,
No sneaky doors for strangers through.
🐇✨ The blog now bounces safer too.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the dependency consolidation change, though the PR also includes related security hardening.
Description check ✅ Passed The description covers the dependency updates, but it omits the required 'Fixes #' line and uses 'Changes' instead of 'Proposed Changes'.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/consolidated-dependency-updates

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
app/pyproject.toml (1)

18-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move ruff and filelock out of the main dependency set.
ruff already appears in the dev extra, and filelock is only used from tests/e2e/conftest.py; keeping either in dependencies makes production installs carry non-runtime packages.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/pyproject.toml` around lines 18 - 19, Move the non-runtime packages out
of the main dependency list in the app project configuration: `ruff` should only
remain under the `dev` extra, and `filelock` should be removed from
`dependencies` since it is only used by `tests/e2e/conftest.py`. Update the
dependency sections in `pyproject.toml` so production installs no longer pull in
these packages, while keeping the existing development/test setup intact.
app/routes/admin_panel_users.py (1)

28-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Good early authz guard; it leaves a dead branch downstream.

Rejecting non-admins before the POST handling at Line 34 is the right fix. As a side effect, the later if user.role == "admin" at Line 49 is now always true, and its else block at Lines 76-81 is unreachable. Consider collapsing the if/else to remove the dead branch for clarity.

♻️ Suggested cleanup (lines 49, 76-81)
-        if user.role == "admin":
-            query = User.query
-            users_objects, page, total_pages = paginate_query(query)
+        query = User.query
+        users_objects, page, total_pages = paginate_query(query)

-            users = [
+        users = [
                 (
                     u.user_id,
                     ...
                 )
                 for u in users_objects
-            ]
+        ]

-            Log.info(f"Rendering admin_panel_users.html: params: users={len(users)}")
+        Log.info(f"Rendering admin_panel_users.html: params: users={len(users)}")

-            return render_template(
+        return render_template(
                 "admin_panel_users.html",
                 users=users,
                 page=page,
                 total_pages=total_pages,
-            )
-        else:
-            Log.error(
-                f"{request.remote_addr} tried to reach user admin panel without being admin"
-            )
-
-            return redirect("/")
+        )

Note: the remote_addr log here is sourced from the connection peer (an IP), so the static-analysis log-injection flag is not actionable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/routes/admin_panel_users.py` around lines 28 - 33, The early admin authz
guard in the user admin panel makes the later role check in the POST handling
redundant, so remove the now-dead branch from the logic in the user admin view.
Update the control flow around the existing user role check in the admin panel
handler so the `if user.role == "admin"` path is handled directly and the
unreachable `else` block is deleted, keeping the `POST` logic clear and linear.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/routes/login.py`:
- Around line 37-42: The login redirect validation in the direct-target handling
allows backslash-based and scheme-relative targets to slip through because
urlparse() does not flag them as off-site. Update the redirect guard in the
login route’s direct redirect logic to reject any target containing backslashes
or starting with double slashes before reaching redirect(), alongside the
existing scheme/netloc checks, so only safe relative paths are accepted.

---

Nitpick comments:
In `@app/pyproject.toml`:
- Around line 18-19: Move the non-runtime packages out of the main dependency
list in the app project configuration: `ruff` should only remain under the `dev`
extra, and `filelock` should be removed from `dependencies` since it is only
used by `tests/e2e/conftest.py`. Update the dependency sections in
`pyproject.toml` so production installs no longer pull in these packages, while
keeping the existing development/test setup intact.

In `@app/routes/admin_panel_users.py`:
- Around line 28-33: The early admin authz guard in the user admin panel makes
the later role check in the POST handling redundant, so remove the now-dead
branch from the logic in the user admin view. Update the control flow around the
existing user role check in the admin panel handler so the `if user.role ==
"admin"` path is handled directly and the unreachable `else` block is deleted,
keeping the `POST` logic clear and linear.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6e116d55-7a6c-4922-979f-30cbbf9bacde

📥 Commits

Reviewing files that changed from the base of the PR and between 8f9f35c and bad6629.

⛔ Files ignored due to path filters (1)
  • app/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • app/pyproject.toml
  • app/routes/admin_panel_users.py
  • app/routes/login.py
  • app/settings.py

Comment thread app/routes/login.py
Comment on lines +37 to +42
if direct:
parsed = urlparse(direct)
if parsed.netloc or parsed.scheme or not direct.startswith("/"):
direct = "/"
else:
direct = "/"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python3 - <<'PY'
from urllib.parse import urlparse
for t in ["/\\evil.com", "//evil.com", "/\\/\\evil.com", "javascript:alert(1)"]:
    p = urlparse(t)
    print(repr(t), "netloc=", repr(p.netloc), "scheme=", repr(p.scheme), "startswith/=", t.startswith("/"))
PY

Repository: DogukanUrker/FlaskBlog

Length of output: 405


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

path = Path("app/routes/login.py")
print("FILE_EXISTS", path.exists())
print("LINE_COUNT", sum(1 for _ in path.open()))

with path.open() as f:
    lines = f.readlines()

for start, end in [(1, 120)]:
    print(f"\n--- {path} lines {start}-{end} ---")
    for i in range(start-1, min(end, len(lines))):
        print(f"{i+1:4d}: {lines[i].rstrip()}")
PY

Repository: DogukanUrker/FlaskBlog

Length of output: 4187


Reject backslash-based redirect targets in app/routes/login.py:37-42. urlparse() leaves /\evil.com with empty netloc/scheme, so it passes this guard even though browsers can interpret the backslash as a slash and treat the redirect as off-site. Block \ (and //) before calling redirect().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/routes/login.py` around lines 37 - 42, The login redirect validation in
the direct-target handling allows backslash-based and scheme-relative targets to
slip through because urlparse() does not flag them as off-site. Update the
redirect guard in the login route’s direct redirect logic to reject any target
containing backslashes or starting with double slashes before reaching
redirect(), alongside the existing scheme/netloc checks, so only safe relative
paths are accepted.

@DogukanUrker DogukanUrker merged commit 05ae33c into main Jun 27, 2026
2 of 4 checks passed
@DogukanUrker DogukanUrker deleted the feat/consolidated-dependency-updates branch June 27, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant