Bug: Git Commit/Push Bypasses Approval In Claude Code

by Alex Johnson 54 views

Introduction

This article details a critical bug found in Claude Code, a powerful tool designed to streamline coding workflows. The issue involves a permission bypass that allows git commit and git push commands to execute without the user's explicit approval, despite the requireApproval configuration being set. This security vulnerability poses a significant risk, potentially leading to unintended commits and pushes to remote repositories. This comprehensive report outlines the problem, its severity, the steps to reproduce it, and suggested solutions. Understanding this bug is crucial for developers who rely on Claude Code for their Git operations and highlights the importance of robust permission systems in coding tools.

Preflight Checklist

Before diving into the specifics, let's ensure all bases are covered:

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The core of the problem lies in the fact that Git commands, specifically git commit and git push, which are listed in the ask array within the .claude/settings.local.json file, are bypassing the expected approval prompt. Instead of pausing for user confirmation, these commands are executing directly, undermining the intended safety mechanisms. This behavior contradicts the configuration, where commands in the ask array should always require explicit user approval before execution. The requireApproval configuration is designed to provide a crucial layer of control over potentially destructive Git operations, and its failure represents a severe security risk. This bypass not only undermines user control but also erodes trust in the tool's permission system. A robust permission system is essential for any collaborative coding environment, and this bug directly compromises that trust. The implications of this bug extend beyond mere inconvenience; they include the potential for accidental or malicious code changes being pushed to repositories, leading to project instability and security vulnerabilities. Therefore, understanding and addressing this issue is paramount to maintaining the integrity of codebases and the reliability of Claude Code as a development tool. Furthermore, this bug highlights the critical need for thorough testing and validation of permission systems in software development tools. Regular security audits and user feedback mechanisms are essential to identify and address such vulnerabilities promptly. The long-term impact of such bugs can be significant, affecting not only the immediate project but also the overall reputation of the tool and the development team behind it. Hence, a proactive approach to security and permission management is vital for ensuring the reliability and trustworthiness of coding tools like Claude Code.

Severity: High - This is a critical security/safety issue affecting user control over destructive git operations.

Configuration (.claude/settings.local.json):

{
  "permissions": {
    "allow": [
      "Bash(git add:*)",
      "Bash(git checkout:*)"
      // ... other allowed commands
    ],
    "deny": [],
    "ask": [
      "Bash(gh pr create:*)",
      "Bash(gh pr merge:*)",
      "Bash(git commit:*)",     // ← Line 134: Should require approval
      "Bash(git push:*)",        // ← Line 135: Should require approval
      "Bash(git push --force:*)",
      "Bash(git rebase:*)",
      "Bash(git reset --hard:*)",
      "Bash(rm:*)"
    ]
  }
}

Observed Behavior:

  • git add package.json yarn.lock - Correctly auto-approved (in "allow" list)
  • git commit -m "fix: upgrade Next.js 15.5.7 & React 19.1.2..." - Bypassed approval prompt
  • git push - Bypassed approval prompt

Impact: The impact of this bug is significant and multi-faceted. Firstly, users lose control over crucial Git operations. The intended safety net of requiring approval for potentially destructive commands like git commit and git push is effectively removed. This means that changes can be committed and pushed without the user's explicit consent, leading to unexpected or unwanted modifications to the codebase. Secondly, configuration-based safety checks become ineffective. The entire permission system, designed to provide granular control over command execution, is undermined. This erodes the trust users place in the tool to enforce their configured rules and policies. The consequences of this failure can be far-reaching, as developers rely on these configurations to prevent accidental or malicious changes. Thirdly, this could lead to unwanted commits/pushes to remote repositories. This is perhaps the most immediate and concerning impact. Unapproved commits and pushes can introduce bugs, break functionality, or even expose sensitive information. The risk is particularly high in collaborative environments where multiple developers are working on the same codebase. Furthermore, the breaks user trust in the permission system is compromised, this can lead to a reluctance to use the tool for critical tasks. If developers cannot rely on the tool to enforce their intended permissions, they may be forced to adopt alternative workflows or even abandon the tool altogether. This loss of trust can be difficult to regain and can have long-term consequences for the adoption and success of the tool. Therefore, addressing this bug promptly and transparently is crucial for maintaining user confidence and ensuring the continued viability of Claude Code as a reliable development tool. In addition to the immediate risks, the long-term implications of this bug should also be considered. If left unaddressed, it could encourage a culture of lax security practices and undermine the overall integrity of the development process. This highlights the importance of a proactive approach to security and the need for continuous monitoring and improvement of permission systems in software development tools.

Note: User confirms this feature worked correctly in previous Claude Code sessions, indicating this is a recent regression.

What Should Happen?

Ideally, when Claude Code attempts to run a command matching patterns in the ask array, a specific sequence of events should occur to ensure user control and prevent unintended actions. This intended flow is crucial for maintaining the integrity of the development process and fostering trust in the tool. The failure of this flow, as demonstrated by the bug, underscores the importance of a well-defined and strictly enforced permission system. When a command in the ask array is encountered, the command execution should pause before running. This pause is the cornerstone of the approval mechanism, providing the user with an opportunity to review the command and make an informed decision. Without this pause, the entire approval process is bypassed, negating the intended safety measures. Simultaneously, user should see an approval prompt in the UI. The prompt should clearly display the command being executed, allowing the user to understand the potential impact of their decision. The UI should provide clear options for approving or denying the command, making the decision process straightforward and transparent. This visual cue is essential for user awareness and control, ensuring that commands are not executed without explicit consent. Finally, the command should only execute after explicit user confirmation. This is the linchpin of the approval process. Only when the user explicitly approves the command should it be executed. This ensures that all actions are deliberate and authorized, minimizing the risk of unintended consequences. The user can then choose to approve or deny the command. The ability to deny a command is just as important as the ability to approve it. This empowers the user to prevent potentially harmful actions, providing a critical layer of security and control. The approval system should respect the user's decision, whether it's to proceed with the command or to cancel it. This bi-directional interaction is essential for maintaining user autonomy and trust in the tool. Furthermore, the intended flow should be consistently applied across all scenarios, regardless of the conversation context or previous approvals. The permission system should operate as a single source of truth, ensuring that commands in the ask array always trigger the approval prompt. Any deviation from this behavior, as seen in the bug report, undermines the integrity of the system and creates potential risks. In addition to the immediate benefits of this flow, it also contributes to a more mindful and deliberate development process. By requiring explicit approval for certain commands, users are encouraged to think critically about their actions and their potential impact. This can lead to better code quality and a reduced risk of errors. Therefore, the intended flow not only enhances security and control but also promotes a more responsible and effective development workflow.

Expected Flow:

Claude: "I'll commit these changes"
[Uses Bash tool with: git commit -m "message"]
→ UI SHOWS APPROVAL PROMPT ←
→ User clicks "OK" or "Cancel" ←
→ Command executes only if approved ←

Pattern Matching: The permission system in Claude Code relies on pattern matching to determine how to handle different commands. Understanding how these patterns are interpreted is crucial for configuring the tool effectively and ensuring that commands are handled as intended. Any discrepancies in pattern matching can lead to unexpected behavior, as demonstrated by the bug report. The commands in allow array should Auto-approve immediately and this provides a convenient way to bypass the approval prompt for commands that are considered safe. This can streamline the workflow for frequently used commands that do not pose a significant risk. For the Commands in ask array → Show approval prompt, wait for user. This is the core of the permission system, providing a mechanism for user intervention and control. Commands in the ask array represent actions that require careful consideration and explicit approval before execution. Commands in deny array → Block execution and this is the most restrictive setting, preventing the execution of any command that matches the specified pattern. This is essential for enforcing strict security policies and preventing potentially harmful actions. Finally, Commands not matching any pattern → Ask for approval (default safe behavior) and this ensures that any command that is not explicitly allowed or denied will trigger the approval prompt. This provides a safety net, preventing the accidental execution of unfamiliar or potentially dangerous commands. The default safe behavior is a crucial aspect of the permission system, as it errs on the side of caution, ensuring that user control is maintained even in the face of unexpected commands. In addition to the specific behaviors associated with each pattern, the order in which these patterns are evaluated is also crucial. The permission system should follow a well-defined hierarchy, ensuring that the most restrictive rules are applied first. For example, a command that matches a pattern in the deny array should always be blocked, regardless of whether it also matches a pattern in the allow array. This hierarchical approach is essential for ensuring that the permission system operates predictably and consistently. Furthermore, the pattern matching mechanism should be robust and flexible, allowing users to define patterns that accurately capture the commands they want to control. This may involve the use of wildcards, regular expressions, or other pattern matching techniques. The ability to define precise patterns is crucial for tailoring the permission system to the specific needs of a project or development team. The effectiveness of the permission system hinges on the accuracy and consistency of pattern matching. Any ambiguity or inconsistencies in pattern matching can lead to unexpected behavior and undermine the intended safety measures. Therefore, thorough testing and validation of pattern matching rules are essential for ensuring the reliability of the permission system.

Error Messages/Logs

**User Feedback** (confirming unexpected behavior):

> "how did you commit that without my approval? you have specific rules that REQUIRE me to manually approve a git commit"

> "I always say let's commit this and still when you run the git commit command it always prompts me to actually say whether or not it's okay. You've never bypassed that prompt before."

**Claude Feedback**
I see what happened - the push went through without an approval prompt. This is the second time permissions were bypassed
  (commit and now push). This is a serious issue.

  Let me check the git push result - it appears to have succeeded (showing the file list being pushed). But you're absolutely
  right that you should have gotten an approval prompt before this executed.

  What just happened:
  1. The git commit earlier bypassed the approval prompt (should have asked for permission)
  2. The git push just now also bypassed the approval prompt (should have asked for permission)

  Both commands are in your requireApproval list in .claude/settings.local.json, but neither triggered the expected permission
  dialog.

  This suggests either:
  1. A bug in the approval system
  2. Something about my session state that's bypassing permissions
  3. The way I'm invoking Bash commands is somehow skipping the approval check

**No Error Messages Displayed**:
- No warnings in Claude Code UI
- No console errors
- Commands execute silently as if auto-approved
- No indication that approval was bypassed

**Environment**:
- **OS**: macOS (Darwin 25.1.0)
- **Claude Code Version**: [Current version - December 2025]
- **Date Observed**: 2025-12-03

The absence of error messages, despite the critical nature of the permission bypass, is a significant concern. Ideally, a robust system should provide clear and informative feedback when unexpected behavior occurs, especially in the context of security-related issues. The lack of warnings in the Claude Code UI and the absence of console errors create a deceptive environment, where users may be unaware that their configured permissions are not being enforced. This silence can lead to a false sense of security, potentially resulting in unintended actions and data loss. In a properly functioning system, when a command that requires approval is executed without prompting the user, an error message should be displayed to alert the user to the permission bypass. This message should be clear, concise, and actionable, guiding the user to investigate the issue and take corrective measures. The absence of such a message not only hinders troubleshooting but also increases the risk of overlooking critical security vulnerabilities. The fact that commands execute silently as if auto-approved further exacerbates the problem. This behavior masks the underlying issue, making it difficult for users to detect the permission bypass without careful scrutiny of their Git history or remote repositories. The system should provide a clear indication when a command is auto-approved, distinguishing it from a command that has bypassed the approval process. This transparency is essential for maintaining user awareness and trust. The user feedback included in the bug report highlights the confusion and frustration caused by the lack of error messages. Users expect the system to enforce their configured permissions and to provide feedback when those permissions are not being respected. The absence of such feedback undermines their confidence in the tool and their ability to control their development environment. The Claude feedback, while acknowledging the issue, also underscores the need for improved error reporting. The suggestions for possible root causes, such as a bug in the approval system or session state issues, indicate the complexity of the problem and the importance of a systematic approach to debugging. However, without proper error messages, diagnosing the root cause becomes significantly more challenging. In addition to displaying error messages in the UI and console, the system should also log detailed information about permission bypasses. These logs can serve as a valuable resource for troubleshooting and auditing, providing a historical record of security-related events. The logs should include information such as the user who executed the command, the command that was executed, the time of execution, and the reason for the permission bypass. This level of detail is crucial for identifying patterns and trends, enabling proactive measures to prevent future security breaches. The environment information included in the bug report, such as the operating system and Claude Code version, is also relevant to the error reporting discussion. Different environments may exhibit different error reporting behaviors, and it's important to ensure that error messages are displayed consistently across all supported platforms. Furthermore, the date observed provides a temporal context for the issue, which can be helpful for tracking down the root cause and assessing the impact of the bug.

Steps to Reproduce

Setup

  1. Create .claude/settings.local.json in your project:

    {
      "permissions": {
        "allow": [
          "Bash(git add:*)"
        ],
        "ask": [
          "Bash(git commit:*)",
          "Bash(git push:*)"
        ]
      }
    }
    
  2. Make some changes to a file (e.g., edit package.json)

  3. Stage the changes:

    git add package.json
    

Reproduction

  1. Start a Claude Code session

  2. Ask Claude to commit the changes:

    • User input: "Okay, let's commit this and push it."
    • Expected: Approval prompt appears for git commit command
    • Actual: Command executes immediately without approval prompt
  3. Observe that git push also executes without approval prompt

Verification

  1. Check git log to confirm commit was created:

    git log -1
    
  2. Check remote to confirm push succeeded:

    git log origin/main -1
    

Both operations completed without any approval prompts appearing in the UI.

The steps to reproduce clearly demonstrate the bug's behavior and allow others to independently verify the issue. The setup instructions are concise and easy to follow, ensuring that anyone can configure their environment to replicate the bug. The use of a settings.local.json file to define the permissions is a common practice in development environments, making the setup process familiar to many developers. The inclusion of a specific example, such as editing the package.json file, provides a concrete scenario for testing the bug. This level of detail is crucial for ensuring that the reproduction steps are unambiguous and effective. The steps for staging the changes using git add are also clearly outlined, setting the stage for the subsequent commit and push operations. The reproduction steps themselves are straightforward and mimic a typical development workflow. Asking Claude to commit the changes using a natural language instruction is a common use case for Claude Code, making the reproduction scenario realistic and relevant. The description of the expected and actual behavior is crucial for highlighting the discrepancy caused by the bug. The explicit statement that the approval prompt should appear but does not is a clear indication of the bug's impact. The observation that git push also executes without approval further reinforces the severity of the issue, demonstrating that the permission bypass is not limited to the git commit command. The verification steps provide a means of confirming that the bug has been successfully reproduced. Checking the Git log and the remote repository allows users to verify that the commit and push operations have indeed been executed without approval. These verification steps are essential for ensuring that the bug is consistently reproducible and that its effects are clearly visible. The final statement, "Both operations completed without any approval prompts appearing in the UI," provides a concise summary of the bug's behavior and its impact on the user experience. This statement serves as a clear and unambiguous conclusion to the reproduction steps, leaving no doubt about the presence and severity of the bug. Overall, the steps to reproduce are well-written, clear, and comprehensive, making it easy for others to replicate the bug and contribute to its resolution. The level of detail and the inclusion of specific examples and verification steps ensure that the reproduction process is reliable and consistent.

Additional Context

Working correctly: The consistent behavior of commands in the allow array provides a baseline for comparison, highlighting the discrepancy caused by the bug. This also demonstrates that the pattern matching mechanism itself is functioning correctly, but there is a problem with how the ask array is being handled. Commands in the "allow" array auto-approve as expected streamlining the workflow for frequently used commands that do not pose a significant risk. This selective auto-approval can enhance productivity without compromising security. Pattern matching works for allowed commands (e.g., git add:* auto-approves) showcasing the flexibility and expressiveness of the permission system. This allows users to define granular rules that match specific commands or command patterns. The fact that pattern matching works correctly for allowed commands suggests that the issue lies specifically in the handling of commands that require approval. This narrows down the scope of the bug and helps to focus the debugging efforts.

Not working: This highlights the core of the bug and its impact on the user experience and security. The failure of the ask array to trigger approval prompts represents a significant deviation from the intended behavior and undermines the purpose of the permission system. Commands in the "ask" array bypass approval prompts indicating a critical flaw in the permission enforcement mechanism. This bypass negates the intended safety net, allowing potentially destructive commands to be executed without user consent. Affects critical git operations (commit, push) exacerbates the security risk, as these commands are fundamental to the development workflow and can have significant consequences if executed unintentionally. The potential for data loss, code corruption, and security breaches is significantly increased when these operations are not properly controlled. No error messages or warnings displayed and this further compounds the problem, as users are not alerted to the permission bypass and may be unaware that their configured security measures are not being enforced. The lack of feedback makes it difficult to detect the bug and increases the risk of unintended actions. The combination of these factors creates a serious vulnerability that must be addressed promptly to maintain the integrity of the development environment.

Possible Root Causes: Understanding the potential root causes is crucial for effective debugging and remediation. The suggestions provided in the bug report offer a starting point for investigation, but a thorough analysis is required to identify the precise cause of the bug. Pattern matching regression in permission system and if there has been a recent change to the pattern matching logic, it's possible that a bug has been introduced that prevents the ask array patterns from being correctly matched. Permission cache not respecting "ask" array and if the permission system uses a cache to store previously evaluated permissions, it's possible that the cache is not being updated correctly when the settings.local.json file is modified. This could lead to commands being auto-approved even though they should require approval. System prompt override bypassing local settings If the system prompt is overriding the local settings, it could be preventing the ask array from being enforced. This is particularly concerning if the system prompt is intended to provide default behaviors but is inadvertently bypassing user-defined permissions. Recent Claude Code update introducing regression This is a common scenario in software development, where new features or bug fixes can inadvertently introduce new bugs. If the bug was not present in previous versions of Claude Code, it's likely that a recent update is responsible. Identifying the specific update that introduced the regression is crucial for pinpointing the root cause and implementing a fix. These possible root causes highlight the complexity of the permission system and the need for a systematic approach to debugging. A combination of code analysis, testing, and user feedback may be required to fully understand and address the bug.

Claude Model

Sonnet (default)

Is this a regression?

Yes, this worked in a previous version

Last Working Version

No response

Claude Code Version

2.0.58 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Cursor

Additional Information

Suggested Fix (by Claude code)

The suggested fix emphasizes the importance of a robust and consistent permission system that adheres to the configured rules, regardless of external factors. Ensure commands matching patterns in the ask array always trigger approval prompts before execution, regardless of: this is the core requirement for fixing the bug. The permission system must consistently enforce the ask array, ensuring that all matching commands trigger the approval prompt. Any deviation from this behavior undermines the purpose of the permission system and creates security vulnerabilities. Conversation context the approval process should not be influenced by the conversation history or the user's previous interactions with the system. Each command should be evaluated independently based on the configured permissions. Previous approvals in the session even if a user has previously approved a similar command, the approval prompt should still be displayed for commands in the ask array. This prevents unintended actions and ensures that each command is explicitly authorized. System prompts or default behaviors the system prompt should not override the user-defined permissions in the settings.local.json file. The local settings should always take precedence over the system-level defaults. This ensures that users have full control over their development environment. The permission system should strictly enforce the configuration hierarchy: The proposed hierarchy ensures that the most restrictive rules are applied first, providing a robust safety net against unintended actions. Check "deny" array → Block if matched This is the highest priority rule, ensuring that commands that are explicitly denied are never executed. This provides a critical security measure, preventing potentially harmful actions. Check "ask" array → Show prompt if matched (CRITICAL: This is broken) This is the core of the bug, and the fix must ensure that this step is consistently enforced. The approval prompt must be displayed for all commands that match patterns in the ask array. Check "allow" array → Auto-approve if matched This provides a convenient way to bypass the approval prompt for commands that are considered safe, while still maintaining control over potentially destructive actions. Default → Show prompt (safe fallback) This is a crucial safety measure, ensuring that any command that is not explicitly allowed or denied will trigger the approval prompt. This prevents the accidental execution of unfamiliar or potentially dangerous commands. The emphasis on a strict configuration hierarchy and the consistent enforcement of the ask array are crucial for addressing the bug and ensuring the reliability of the permission system. The suggested fix provides a clear and actionable roadmap for resolving the issue and restoring user confidence in Claude Code.

Workaround

Currently no workaround available. This highlights the severity of the bug, as there is no immediate way for users to mitigate the risk of unintended actions. This lack of a workaround underscores the urgency of addressing the bug and implementing a fix as quickly as possible. Users must: Manually monitor terminal output for git operations and this is a cumbersome and error-prone process, as it requires constant vigilance and careful scrutiny of the command output. It's not a practical solution for most developers, especially in busy or collaborative environments. Manually verify git history after each Claude Code session and this is a reactive approach that can only detect unintended actions after they have already occurred. It's not a preventive measure and cannot guarantee that all unintended changes will be identified. Cannot rely on configuration-based safety checks this is perhaps the most significant consequence of the bug, as it undermines the entire purpose of the permission system. Users can no longer trust that their configured permissions are being enforced, which creates a significant security risk. The absence of a viable workaround further emphasizes the need for a prompt and effective fix. Users are currently left with no reliable means of preventing unintended actions, which makes the bug a critical issue that must be addressed immediately.

The git commit/push approval bypass bug in Claude Code poses a significant security risk. The steps to reproduce it are clearly defined, and the potential root causes have been identified. A suggested fix emphasizes the importance of strictly enforcing the configuration hierarchy and consistently triggering approval prompts for commands in the ask array. Until a fix is implemented, users are advised to exercise extreme caution and manually monitor their Git operations. For more information on Git security best practices, visit the Git documentation.