require_tls only enforced on RFC 6764 discovery, not on explicit URLs
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 62/100
- Issue type
- Documentation
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- python
- Domain
- documentation
Research direction
Read the require_tls documentation and the DAVClient and AsyncDAVClient constructor docstrings; the issue does not name specific files. Clarify that the option currently applies to RFC 6764 discovery, not explicitly supplied URLs, and that global enforcement is deferred to 4.0. Done means the documented scope matches the current behavior.
Written by the indexing model from the issue text.
Description
require_tls was added together with the .well-known forwarding, as one out of two measures to prevent a man-in-the-middle-attack. However, something went wrong because in the current main the configuration option is not checked anywhere. In the current v3.3.0-dev branch and future v3.3.0-release there is a fix which will honor this variable but only for well-known forwarding. I think this is silly, it should be for all connections.
Now True is and should be the default. If doing this for all connections, it will be a breaking change - so it's procrastinated until the 4.0-release.
I was too lazy to create this issue myself, so below is the initial text from Claude.
⚠️ This issue is AI-generated (Claude Opus 4.8 via Claude Code) on behalf of tobixen ⚠️
Summary
require_tls is named and documented as if it guarantees a TLS-only connection, but it currently only gates the RFC 6764 discovery path. When a fully-qualified URL is passed explicitly, the parameter has no effect.
Current behaviour (v3.3.x)
The parameter is threaded only through discovery:
DAVClient.__init__ / AsyncDAVClient.__init__ → _auto_url(require_tls=...) → discover_caldav(require_tls=...) → discover_service (where d6267c78 closed the well-known-redirect hole).
But _auto_url returns early for any URL containing /, so discovery — and therefore the require_tls check — is skipped entirely. Result:
# require_tls=True is the DEFAULT, yet this connects over plaintext:
DAVClient(url="http://caldav.example.com/dav/", username=..., password=...)
A parameter literally named require_tls does not require TLS for the connection actually made. This is a name/behaviour mismatch and a potential downgrade footgun.
Proposed fix (deferred to 4.0)
Make enforcement global rather than discovery-only:
- Add a shared
BaseDAVClient._enforce_require_tls(url)helper (there is no shared__init__today — the two constructors are separate). - Call it from both
DAVClient.__init__andAsyncDAVClient.__init__right after URL objectification, rejecting non-httpsURLs whenrequire_tls=True. - Update docstrings + CHANGELOG.
Why this is deferred (breaking change)
require_tls defaults to True. Making it global would reject every explicitly-passed http:// URL by default, which breaks real usage:
- The project's own docker integration test servers (Cyrus, SOGo, Baikal, …) are all
http://localhost:PORT/.... - Anyone running an internal/LAN CalDAV server over plain HTTP with default args.
So this changes the default security posture and is a breaking change — appropriate for a major release (4.0), with require_tls=False threaded through the test config.
Out of scope for the constructor check
A constructor-time scheme check does not catch an https → http downgrade via redirect during live requests. If "applies to any connection" is taken literally, the per-request path in each client needs enforcement too — worth tracking separately.
Decision
For now: keep require_tls discovery-only and document the scope precisely (done alongside this issue). Revisit global enforcement in 4.0.
⚠️ This issue is AI-generated (Claude Opus 4.8 via Claude Code) on behalf of tobixen ⚠️
- Dominant language
- Python
- Stars
- 412
- Forks
- 113
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 34
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from python-caldav/caldav
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
python-caldav/caldav#763 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
python-caldav/caldav#761 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
python-caldav/caldav#725 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 48/100
python-caldav/caldav#720 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 30/100
python-caldav/caldav#704 ·
Maintainers usually reply within 1 day
All issues in python-caldav/caldav
Similar issues
-
area: agents area: docs good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
openapi/gknowledge#23 ·
-
get() for StrEnumPossibly taken @FeJo5952 claimed this today. Opengood first issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
collective/icalendar#1921 · 1 comment ·
Maintainers usually reply within 1 day
-
Improvement Python Spans
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
getsentry/sentry-python#7994 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
alphagov/notifications-api#5004 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
equinor/radix-flux#3922 ·
Maintainers usually reply within 1 day