Skip to content

Fix pickle RCE vulnerability in Pro app API#111

Open
patrickkidd-hurin wants to merge 1 commit intomasterfrom
feat/fix-pickle-rce-vuln
Open

Fix pickle RCE vulnerability in Pro app API#111
patrickkidd-hurin wants to merge 1 commit intomasterfrom
feat/fix-pickle-rce-vuln

Conversation

@patrickkidd-hurin
Copy link
Copy Markdown
Collaborator

Summary

  • Vulnerability: All 20 pickle.loads(request.data) calls in pro/routes.py accept arbitrary pickle payloads from clients, enabling remote code execution (RCE) on the server
  • Fix: Introduced RestrictedUnpickler in btcopilot/pro/safe_pickle.py that allowlists only safe types (builtins, datetime, collections) for request data, and additionally allows PyQt5.QtCore types for diagram database blobs
  • No API or schema changes — the fix is transparent to Pro app clients since they only send safe builtin types

Changes

File Change
btcopilot/pro/safe_pickle.py New module with safe_loads() and safe_loads_diagram()
btcopilot/pro/routes.py All 20 pickle.loads(request.data)safe_loads(request.data)
btcopilot/pro/models/diagram.py pickle.loads(self.data)safe_loads_diagram(self.data) (defense-in-depth)
btcopilot/tests/pro/test_safe_pickle.py 27 tests covering allowed types + blocked RCE payloads

Test plan

  • 27 new tests: builtins allowed, RCE payloads blocked (os.system, subprocess, eval, exec), PyQt5 allowed only in diagram context
  • 124 existing Pro tests pass (3 pre-existing setup errors unrelated to this change)

🤖 Generated with Claude Code

Replace all pickle.loads(request.data) calls with a RestrictedUnpickler
that only allows safe builtin types (dict, list, str, int, etc.), blocking
arbitrary code execution via crafted pickle payloads.

- Add btcopilot/pro/safe_pickle.py with two restricted unpicklers:
  - safe_loads(): for untrusted client request data (builtins only)
  - safe_loads_diagram(): for database blobs (builtins + PyQt5.QtCore)
- Update routes.py: all 20 pickle.loads(request.data) → safe_loads()
- Update diagram.py: pickle.loads(self.data) → safe_loads_diagram()
- Add 27 tests covering allowed types and blocked RCE payloads

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gitguardian
Copy link
Copy Markdown

gitguardian bot commented Mar 11, 2026

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
28272816 Triggered Generic Password 3c357f4 btcopilot/tests/pro/test_safe_pickle.py View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the security of the Pro app API by mitigating a Remote Code Execution (RCE) vulnerability. It replaces all direct uses of pickle.loads with custom, restricted unpickling functions that strictly control which Python types can be deserialized from incoming client requests. This change ensures that the application only processes safe data, preventing malicious payloads, while maintaining compatibility with existing client interactions and allowing specific PyQt5 types for diagram data where necessary.

Highlights

  • Addressed RCE Vulnerability: Fixed a critical Remote Code Execution vulnerability by restricting pickle.loads usage across the Pro app API.
  • Introduced Safe Unpicklers: Implemented safe_loads for general client request data and safe_loads_diagram specifically for diagram data, allowing only whitelisted types and PyQt5.QtCore types respectively.
  • Transparent to Clients: The security fix was applied without requiring any API or schema changes, ensuring backward compatibility for Pro app clients.
Changelog
  • btcopilot/pro/models/diagram.py
    • Modified pickle.loads(self.data) to safe_loads_diagram(self.data) to apply restricted unpickling to diagram data, allowing specific PyQt5 types.
  • btcopilot/pro/routes.py
    • Updated all 20 instances of pickle.loads(request.data) to use the newly introduced safe_loads(request.data) for enhanced security.
  • btcopilot/pro/safe_pickle.py
    • Introduced a new module containing _RestrictedUnpickler and _DiagramUnpickler classes, along with safe_loads and safe_loads_diagram functions to provide secure deserialization.
  • btcopilot/tests/pro/test_safe_pickle.py
    • Added comprehensive unit tests (27 new tests) to validate that safe built-in types are correctly unpickled, while various RCE payloads and disallowed types are effectively blocked by the new unpicklers.
Activity
  • patrickkidd-hurin created this pull request to address a critical RCE vulnerability.
  • New tests were added to cover allowed types and blocked RCE payloads, including specific checks for PyQt5 types in diagram contexts.
  • Existing Pro tests (124 of them) were run and passed, confirming no regressions were introduced.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@patrickkidd-hurin
Copy link
Copy Markdown
Collaborator Author

\ud83d\udce9 Follow-up queued \u2014 resuming agent session to address 1 comment(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant