Please do not report security vulnerabilities through public GitHub issues, pull requests, or discussions.
Report them privately through GitHub Private Vulnerability Reporting:
- Go to https://github.com/selvaz/LazyTools/security/advisories/new (or the repository's Security → Advisories → Report a vulnerability button).
- Fill in the affected version, a description, and reproduction steps.
GitHub delivers the report to the maintainers privately and gives us a place to collaborate on a fix and coordinate disclosure.
Maintainer contact. If Private Vulnerability Reporting is unavailable to you, contact the maintainer (
selvaz) via the email on the GitHub profile and mark the subject[SECURITY] LazyTools. Replace this with a dedicated security mailbox once one is established.
Please include, where possible:
- The affected version (
pip show lazytoolkit) and Python version. - A minimal reproduction and the impact you observed.
- Any suggested remediation.
We aim to acknowledge a report within a few business days and to keep you updated as we investigate and ship a fix. Please give us a reasonable window to remediate before any public disclosure.
lazytoolkit is pre-1.0; security fixes land on the latest 0.x release.
Pin a version and watch the CHANGELOG before upgrading.
lazytools provides tool providers and connector clients that talk to external
services. The most relevant security surfaces:
Anything you place in Agent(tools=[...]) can be invoked by the LLM with
LLM-chosen arguments. Treat every tool you expose as attacker-influenced input.
- Gated dangerous actions.
gmail_sendandtelegram_send_messageare gated bylazytools.safety(Allowlist+ one-shotConfirmationGate). The harmless companion (gmail_create_draft) is never gated — dry-run first. - OAuth token files.
GmailClient.from_credentialspersists the cached OAuth token (including the long-lived refresh token) with owner-only (0600) permissions. Store credential and token files outside any world-readable or version-controlled location.
- MCP.
MCP.stdio()andMCP.http()require an explicitallow=(ordeny=) filter — omitting both raisesValueError. Each advertised tool the LLM can call runs inside your process or with the server's permissions, so audit the tool surface before passingallow=["*"]. - Same-origin redirects. The default gateway HTTP client refuses redirects
to a different host or an HTTPS→HTTP downgrade, so the
Authorizationheader is not silently forwarded to an attacker-controlled host. - No result sanitisation.
lazytools.connectors.gatewayforwards each tool's JSON response to the agent unmodified. Sanitising results (stripping secrets, PII, internal identifiers) is the remote gateway's responsibility — do it server-side.
When exposed as a tool, read_docs_tools requires a base_dir; paths that
resolve outside it are refused and oversized files are skipped rather than read.
The skills indexer skips symlinks so an in-tree symlink can't widen the read
surface to unrelated files on disk.
parse_authentication_results only treats DKIM/SPF/DMARC as verified when the
authoritative result says so, ignoring pass substrings inside comments and
extension fields. Pass trusted_authserv_id= to pin the authenticating relay
and reject forged headers from other hosts.
- Vulnerabilities in third-party dependencies (
google-api-python-client,httpx, themcpSDK,trafilatura, etc.) — report those upstream, though we're happy to help coordinate. - Secret redaction in agent logs/sessions and at-rest store encryption are
provided by LazyBridge, not
lazytools; see the LazyBridge security policy for those.