BDServer Security Assessment
Overview
This repository contains a security assessment of BDServer, a self-hosted blog and website server written in Python by J.Y. Amihud (known online as Blender Dumbass). BDServer provides features including user accounts, article publishing, comments, federation via ActivityPub, plugin support, and theming.
BDServer is an ambitious project. The codebase spans over 13,000 lines of Python across its core modules, implementing everything from HTTP request handling to a custom markdown parser to ActivityPub federation. For a project maintained by a single developer, this represents significant effort.
The scope of the project creates challenges. Web application security requires attention to many concerns: input validation, output encoding, authentication, session management, cryptographic choices, and more. Addressing all of these correctly across a large codebase is difficult for any team, and especially so for a solo developer working without the support of a security-focused web framework.
This assessment identified several vulnerabilities that follow common patterns. None of them reflect unusual mistakes. They are the kinds of issues that appear regularly in web applications, particularly those built on lower-level HTTP libraries rather than frameworks with built-in protections. The good news is that most can be addressed through targeted fixes, and some architectural changes would make the codebase easier to secure going forward.
Scope
This assessment covers BDServer at commit dc86854a261f61042868a5e73de5272a6f2799db. The assessed code is preserved in two forms:
BDServer/— A snapshot of the source tree for easy browsingBDServer.bundle— A git bundle containing full commit history, restorable withgit clone BDServer.bundle
A few commits have been made since this commit. None appear to address the vulnerabilities described here based on a brief review, but they were not analyzed in depth.
Testing focused on the core server functionality: request handling, authentication, user input processing, and data storage. Federation (both ActivityPub and BDServer's custom federation protocol) was not reviewed. Plugin-specific vulnerabilities were not assessed beyond the plugin management interface itself.
Findings Summary
| # | Vulnerability | Severity | Description |
|---|---|---|---|
| 1 | Path Traversal | High (7.5) | File-serving endpoints allow reading arbitrary files via filter bypass |
| 2 | Stored XSS | High (8.1) | Multiple vectors for injecting JavaScript via comments and profile fields |
| 3 | CSRF | High (7.4) | State-changing operations use GET requests with no token validation |
| 4 | Weak PRNG | High (7.4) | Session tokens generated with predictable random source |
| 5 | Weak Password Hashing | High (7.5) | Passwords stored as unsalted SHA-512 hashes |
| 6 | Insecure Key Storage | Medium (4.4) | Encrypted private keys stored alongside their passwords |
Each finding has a detailed report in its numbered directory, including root cause analysis, reproduction steps, and remediation guidance.
Patterns and Themes
Several patterns emerge across these findings that point to opportunities for architectural improvement.
Manual HTML Construction
The largest source of vulnerabilities is building HTML through string concatenation. Render.py alone contains over 6,000 lines of interleaved Python logic and HTML fragments. Every place where user input is inserted into these strings is a potential XSS vector. The custom Safe() function attempts to prevent this but only escapes angle brackets, leaving attribute injection possible.
Templating engines like Jinja2 solve this problem by escaping variables automatically. They also separate presentation from logic, making the code easier to review and maintain. Migrating to a templating engine would eliminate entire categories of XSS vulnerabilities rather than requiring each insertion point to be audited individually.
HTTP Method Misuse
BDServer uses GET requests for operations that modify server state: posting comments, updating profiles, deleting content, and even installing plugins. This violates HTTP semantics and enables CSRF attacks through simple image tags or links. Combined with the absence of CSRF tokens, attackers can trigger these actions by embedding URLs in external pages or emails.
Moving state-changing operations to POST and adding CSRF tokens would address both the semantic issues and the security vulnerabilities.
Direct Use of Standard Library
BDServer builds on Python's http.server module, which provides basic HTTP handling but none of the security features that web frameworks offer. There are no built-in protections for path traversal, no session management, no CSRF tokens, and no secure cookie handling. Each of these must be implemented manually, and it's easy to miss edge cases.
Web frameworks like Flask or Django exist precisely because these problems have been solved many times before. Adopting a framework (or at least borrowing well-tested components for path handling, session management, and the like) would provide a stronger foundation than reimplementing these from scratch.
Cryptographic Choices
Two findings relate to cryptographic decisions: using Python's random module (which is not cryptographically secure) for session tokens, and using unsalted SHA-512 for password hashing. Both represent common mistakes. The secrets module provides secure random generation, and libraries like argon2-cffi provide proper password hashing with minimal integration effort.
Recommendations
The individual finding reports include specific remediation steps. At a higher level, these changes would improve the security posture and maintainability of BDServer:
-
Adopt a templating engine for HTML generation. This eliminates XSS vulnerabilities structurally rather than relying on manual escaping.
-
Use POST for state-changing operations and implement CSRF tokens. This is a standard web security practice that prevents a class of attacks.
-
Replace the custom markdown parser with an established library. Parsing untrusted input is difficult to get right, and mature libraries have already addressed the edge cases.
-
Use
secretsinstead ofrandomfor anything security-sensitive: session tokens, verification codes, invite codes. -
Use a proper password hashing algorithm like Argon2 or bcrypt. These are designed for the task and resist the attacks that SHA-512 is vulnerable to.
-
Add secure cookie attributes (
HttpOnly,SameSite=Strict) to session cookies as defense in depth. -
Consider containerized deployment as a way to limit the impact of file-read vulnerabilities. A containerized BDServer cannot access the host system's SSH keys or other sensitive files.
None of these changes require rewriting BDServer from scratch. They can be adopted incrementally, prioritizing the highest-impact issues first.
Responsible Disclosure
| Date | Action |
|---|---|
| January 8, 2026 | Assessment started |
| January 21, 2026 | Assessment concluded |
| January 21, 2026 | Developer contacted via Matrix |
| January 21, 2026 | Developer confirmed receipt of report |
| March 22, 2026 | Developer reminded of publication date of report |
| April 22, 2026 | Report repository made public |
Assessor
This assessment was performed by Logan Fick.
Disclaimer
This assessment was performed on a best-effort basis against BDServer commit dc86854 and reflects the state of the software at the time of testing. The findings and remediations are provided for informational purposes and should be independently validated before implementation. This report does not guarantee all vulnerabilities have been identified, nor does it guarantee the suggested fixes will be effective in all environments.