Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add security rules for pymongo and pymssql to detect empty passwords and secrets #97

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ESS-ENN
Copy link
Collaborator

@ESS-ENN ESS-ENN commented Dec 7, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced security rules to prevent empty passwords and hardcoded secrets in Python applications using pymongo and pymssql libraries.
  • Tests

    • Added comprehensive test configurations to validate password handling for both empty and hardcoded password scenarios across pymongo and pymssql.
  • Snapshots

    • Created snapshot files for testing various connection scenarios with empty and hardcoded passwords, enhancing the validation process.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Sakshis seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link

coderabbitai bot commented Dec 7, 2024

Walkthrough

This pull request introduces several new security rules for Python applications using the pymongo and pymssql libraries. It includes rules to detect connections established with empty passwords and hard-coded secrets. Each rule is categorized with a severity level of "warning" and provides guidance on secure credential management practices. Additionally, corresponding test configurations and snapshot files are created to validate these rules, ensuring proper handling of sensitive information in database connections.

Changes

File Path Change Summary
rules/python/security/python-pymongo-empty-password-python.yml New rule added: python-pymongo-empty-password-python to detect empty passwords in MongoClient.
rules/python/security/python-pymongo-hardcoded-secret-python.yml New rule added: python-pymongo-hardcoded-secret-python to identify hard-coded secrets in MongoClient.
rules/python/security/python-pymssql-empty-password-python.yml New rule added: python-pymssql-empty-password-python to detect empty passwords in pymssql.connect.
tests/__snapshots__/python-pymongo-empty-password-python-snapshot.yml New snapshot added for testing MongoClient with empty passwords.
tests/__snapshots__/python-pymongo-hardcoded-secret-python-snapshot.yml New snapshot added for testing MongoClient with hard-coded passwords.
tests/__snapshots__/python-pymssql-empty-password-python-snapshot.yml New snapshot added for testing pymssql with empty passwords.
tests/python/python-pymongo-empty-password-python-test.yml New test configuration added to validate MongoClient handling of passwords.
tests/python/python-pymongo-hardcoded-secret-python-test.yml New test configuration added to validate MongoClient handling of hard-coded secrets.
tests/python/python-pymssql-empty-password-python-test.yml New test configuration added to validate pymssql handling of empty passwords.

Possibly related PRs

Suggested reviewers

  • petrisorcoderabbit
  • harjotgill

Poem

🐰 In the land of code where secrets hide,
A rabbit hops with rules as guide.
Empty passwords? No, not today!
Secure your data, keep risks at bay.
With snapshots and tests, we’ll leap and bound,
For safety in coding, our joy is found! 🌟


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai bot changed the title @coderabbitai Add security rules for pymongo and pymssql to detect empty passwords and secrets Dec 7, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (8)
tests/python/python-pymongo-hardcoded-secret-python-test.yml (2)

15-15: Remove unnecessary semicolon

Python doesn't require semicolons at the end of statements.

-    password = "aaaa";
+    password = "aaaa"

1-16: Consider adding more test cases

The current test cases could be enhanced by adding:

  1. Password from configuration file
  2. Password from secure vault/key management service
  3. Password from connection string
  4. Complex password scenarios with special characters

Would you like me to provide examples for these additional test cases?

tests/python/python-pymongo-empty-password-python-test.yml (1)

17-17: Remove unnecessary semicolon

Python doesn't require semicolons at the end of statements.

-    password = "";
+    password = ""
tests/__snapshots__/python-pymongo-hardcoded-secret-python-snapshot.yml (1)

1-133: Consider adding documentation comments

The snapshot file would benefit from a header comment explaining:

  1. The purpose of the snapshot
  2. How it's generated
  3. When it should be regenerated

Would you like me to provide an example header comment?

rules/python/security/python-pymongo-empty-password-python.yml (1)

16-66: Consider enhancing pattern matching for edge cases

The current patterns might miss some scenarios where empty passwords could be passed:

  1. F-strings: f""
  2. String formatting: "".format()
  3. String interpolation: %s % ""

Consider adding patterns to catch these cases:

 utils:
   match_call:
     # ... existing pattern ...
+  match_f_string:
+    kind: expression_statement
+    has:
+      kind: f_string
+      all:
+        - has:
+            kind: f_string_start
+        - has:
+            kind: f_string_end
rules/python/security/python-pymssql-empty-password-python.yml (1)

4-10: Enhance the security message with specific implications

The current message could be more impactful by including specific security implications and best practices.

Consider updating the message to:

  message: >-
    The application creates a database connection with an empty password.
-   This can lead to unauthorized access by either an internal or external
-   malicious actor. To prevent this vulnerability, enforce authentication
-   when connecting to a database by using environment variables to securely
-   provide credentials or retrieving them from a secure vault or HSM
-   (Hardware Security Module).
+   This is a critical security vulnerability that allows unrestricted database access,
+   potentially exposing sensitive data to unauthorized users. To prevent this:
+   1. Never use empty passwords in any environment
+   2. Use environment variables (e.g., os.environ['DB_PASSWORD'])
+   3. Implement a secrets management solution (e.g., AWS Secrets Manager, HashiCorp Vault)
+   4. Consider using connection pooling with proper authentication
tests/python/python-pymssql-empty-password-python-test.yml (2)

2-23: Expand test coverage for valid scenarios

The current valid test cases could be more comprehensive.

Consider adding these additional test cases:

valid:
  - |
    conn5 = _mssql.connect(
    server='SQL01',
    user='user',
    password=pswd2,
    database='mydatabase'
    )
  - |
    conn6 = _mssql.connect(
    server='SQL01',
    user='user',
    password=os.env['pswd2'],
    database='mydatabase'
    )
  - |
    conn7 = _mssql.connect(
    server='SQL01',
    user='user',
    password=os.getenv('secret'),
    database='mydatabase'
    )
+ - |
+   conn8 = _mssql.connect(
+   server='SQL01',
+   user='user',
+   password=keyring.get_password('system', 'db_password'),
+   database='mydatabase'
+   )
+ - |
+   conn9 = _mssql.connect(
+   server='SQL01',
+   user='user',
+   password=get_secret_from_vault('db_password'),
+   database='mydatabase'
+   )

47-47: Remove trailing whitespace

There's a trailing whitespace at the end of line 47.

-    pswd2 = get_from_config()  
+    pswd2 = get_from_config()
🧰 Tools
🪛 yamllint (1.35.1)

[error] 47-47: trailing spaces

(trailing-spaces)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2f95a8e and 4d5f3ca.

📒 Files selected for processing (9)
  • rules/python/security/python-pymongo-empty-password-python.yml (1 hunks)
  • rules/python/security/python-pymongo-hardcoded-secret-python.yml (1 hunks)
  • rules/python/security/python-pymssql-empty-password-python.yml (1 hunks)
  • tests/__snapshots__/python-pymongo-empty-password-python-snapshot.yml (1 hunks)
  • tests/__snapshots__/python-pymongo-hardcoded-secret-python-snapshot.yml (1 hunks)
  • tests/__snapshots__/python-pymssql-empty-password-python-snapshot.yml (1 hunks)
  • tests/python/python-pymongo-empty-password-python-test.yml (1 hunks)
  • tests/python/python-pymongo-hardcoded-secret-python-test.yml (1 hunks)
  • tests/python/python-pymssql-empty-password-python-test.yml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/snapshots/python-pymongo-empty-password-python-snapshot.yml
🧰 Additional context used
🪛 yamllint (1.35.1)
tests/python/python-pymssql-empty-password-python-test.yml

[error] 47-47: trailing spaces

(trailing-spaces)

🔇 Additional comments (7)
tests/__snapshots__/python-pymongo-hardcoded-secret-python-snapshot.yml (1)

59-59: Update snapshot after fixing test cases

This snapshot contains the semicolon that needs to be removed from the test case. After fixing the issues in the test files, please regenerate this snapshot.

rules/python/security/python-pymongo-empty-password-python.yml (2)

1-15: LGTM: Well-structured metadata with clear security context

The rule metadata is well-defined with appropriate severity level and comprehensive messaging that includes:

  • Clear problem description
  • Security implications
  • Mitigation strategies
  • Relevant CWE/OWASP references

133-136: Verify rule coverage with test cases

The rule combination looks correct. To ensure comprehensive coverage:

  1. Add test cases for various empty password scenarios
  2. Include negative test cases to verify no false positives
✅ Verification successful

Test coverage is comprehensive and validates rule combination

The test file includes:

  • Valid cases: non-empty passwords and environment variable usage
  • Invalid cases: both direct empty string and variable-based empty string assignments
  • Coverage for both patterns in the rule (match_call and match_call_with_string)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if test files exist for this rule
fd -e yml "python-pymongo-empty-password.*test" tests/

Length of output: 115


Script:

#!/bin/bash
# Check the content of the test file to verify coverage
cat tests/python/python-pymongo-empty-password-python-test.yml

Length of output: 453

rules/python/security/python-pymongo-hardcoded-secret-python.yml (2)

1-14: LGTM: Clear security context and guidance

Well-structured metadata with appropriate:

  • Severity level
  • Security implications
  • Mitigation strategies
  • CWE/OWASP references

227-232: Consider optimizing pattern combinations

The current rule uses 4 patterns with some overlap in functionality. Consider:

  1. Consolidating common pattern elements
  2. Using more specific pattern matching to reduce false positives

Also verify the rule's effectiveness:

tests/__snapshots__/python-pymssql-empty-password-python-snapshot.yml (2)

1-281: LGTM! Comprehensive snapshot coverage

The snapshot file provides thorough coverage of the test cases with detailed AST matching labels.


1-281: Verify coverage of all possible empty password scenarios

Let's ensure we're catching all possible empty password scenarios in the codebase.

✅ Verification successful

Empty password detection implementation is comprehensive and accurate

The rule implementation effectively covers all three scenarios of empty password usage in pymssql connections:

  • Direct empty string literals (password='')
  • Empty string through _mssql.connect
  • Variable-based empty strings (pswd = "", password=pswd)

The test cases validate both positive and negative scenarios, including secure alternatives like environment variables and configuration retrieval. The implementation correctly identifies empty password vulnerabilities while allowing legitimate authentication methods.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for potential pymssql connection patterns that might be missed
echo "Checking for potential missed patterns..."

# Check for different empty string patterns
rg -U "password\s*=\s*['\"][\s]*['\"]" --type py

# Check for None password assignments
rg -U "password\s*=\s*None" --type py

# Check for variable assignments that might contain empty strings
ast-grep --pattern 'password = $X' -l python

# Check for potential connection strings or URLs that might contain empty passwords
rg -U "mssql(\+pymssql)?://[^:]+:@" --type py

Length of output: 729


Script:

#!/bin/bash
# Let's first check what Python files exist in the repository
fd '\.py$'

# Then let's check for any test files that might contain pymssql patterns
fd '\.py$' --exec grep -l "pymssql" {}

# Let's also check for any YAML files that might contain Python code snippets
fd '\.ya?ml$' --exec grep -l "pymssql" {}

# Check for any files containing password-related patterns
fd '.' --type f --exec grep -l "password" {}

Length of output: 940


Script:

#!/bin/bash
# Let's examine the rule file and test files to understand the coverage
echo "=== Rule Implementation ==="
cat ./rules/python/security/python-pymssql-empty-password-python.yml

echo -e "\n=== Test Cases ==="
cat ./tests/python/python-pymssql-empty-password-python-test.yml

# Let's also check if there are any other patterns in the test files
echo -e "\n=== Searching for additional password patterns in test files ==="
rg -p "password\s*[:=]" ./tests/python/python-pymssql-empty-password-python-test.yml

Length of output: 8404

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.

2 participants