Skip to content

[test] PR #668 scenario B — bot-only CR (should be ignored)#103

Closed
Eeshu-Yadav-1 wants to merge 2 commits into
openwisp:masterfrom
Eeshu-Yadav-1:test/pr-668-scenario-b-bot-only
Closed

[test] PR #668 scenario B — bot-only CR (should be ignored)#103
Eeshu-Yadav-1 wants to merge 2 commits into
openwisp:masterfrom
Eeshu-Yadav-1:test/pr-668-scenario-b-bot-only

Conversation

@Eeshu-Yadav-1
Copy link
Copy Markdown

Test PR for openwisp/openwisp-utils#668. Only coderabbitai will (auto-)review; the stale bot must NOT process this PR.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a small markdown file used as a test fixture for the “PR #668 scenario B” workflow, ensuring the stale pipeline is not triggered for bot-only code reviews.

Changes:

  • Add TEST_PR_668_B.md containing a single scenario description line.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Eeshu-Yadav
Copy link
Copy Markdown
Collaborator

@coderabbitai please review and request changes for this test PR

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@Eeshu-Yadav
Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces two independent changes: a test scenario documentation note stating that bot-only code reviews should not trigger a stale pipeline, and a new Python module containing intentionally unsafe code patterns. The module demonstrates multiple security vulnerabilities including hardcoded credentials, shell injection via subprocess with shell=True, SQL injection through string concatenation, code injection via eval(), and unsafe file operations with bare exception handling. The module includes a main entry point that accepts user input and processes it through the vulnerable parse_config function.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title follows the required format with [test] prefix and clearly describes the scenario being tested (bot-only CR that should be ignored), matching the PR objectives.
Description check ✅ Passed The description is directly related to the changeset, referencing issue #668 and explaining the test scenario's purpose and constraints for bot behavior.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Bug Fixes ✅ Passed This is a test scenario PR, not a bug fix. It adds intentionally unsafe test code for bot review testing. The bug fix check applies only to core functionality bug fixes, which does not apply here.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Warning

⚠️ This pull request might be slop. It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bad_code_for_review.py`:
- Around line 16-19: The fetch_user function currently builds a tainted SQL
string via concatenation; change it to use parameterized queries/bound
parameters instead of embedding user_id into the SQL text. Replace the string
concatenation in fetch_user with a SQL statement using a placeholder (e.g.,
SELECT * FROM users WHERE id = ?) and return or execute that statement with the
user_id supplied as a separate parameter (or use your DB driver's execute method
with the query plus params). Ensure no user input is interpolated into the SQL
string in fetch_user to prevent SQL injection.
- Around line 22-24: The use of eval in parse_config(data) is executing
untrusted input; replace eval(data) with a proper parser for a constrained
format (e.g., json.loads or a strict YAML parser) and validate the resulting
structure, and make the same replacement for the other occurrence referenced at
lines 34-35; update the parse_config function to return the parsed/validated
dict and add input validation/error handling to reject or sanitize unexpected
types/fields.
- Around line 27-31: The function bare_except contains a destructive call
os.remove("/etc/passwd") and swallows all errors with a bare except: pass;
remove the hardcoded deletion immediately. If the helper is meant to delete
files, change bare_except to accept a validated path parameter, validate against
unsafe targets, call os.remove only on safe paths, and replace the bare except
with specific handlers (e.g., FileNotFoundError, PermissionError) that either
log the error or return a failure status instead of silencing it; ensure you
reference the bare_except function, the os.remove call, and the bare except
block when making the change.
- Around line 11-13: The run_user_command function currently executes raw user
input with subprocess.check_output(..., shell=True), which allows command
injection; replace this with an allowlisted command map and call subprocess
without shell (shell=False) using a list/sequence of arguments: validate the
user's requested command against an allowlist (e.g., a dict mapping safe command
names to fixed argument templates or executable paths), construct the argv list
deterministically (no string concatenation of user input), and call
subprocess.check_output(argv, shell=False); if the input is not allowlisted,
raise an error or return a safe failure response.
- Around line 6-8: The file contains hardcoded secrets in API_KEY and
DATABASE_PASSWORD; remove these literals and read both values from injected
runtime configuration (e.g., environment variables or a secrets/credentials
provider) instead, update any initialization code that references API_KEY or
DATABASE_PASSWORD to fetch process/runtime config (e.g., os.environ or your
config service) and fail fast with a clear error if missing, purge the committed
secrets from the repo history and rotate them if they were ever real, and ensure
you add guidance/docs or .env.example (without real values) so developers know
which keys to supply.

In `@TEST_PR_668_B.md`:
- Line 1: The first line of TEST_PR_668_B.md is not a top-level heading; change
Line 1 to an H1 markdown heading (prefix with "# ") so the file begins with a
single top-level heading to satisfy MD041 and doc consistency; update the first
line content ("Test scenario B: bot-only CR should not trigger stale pipeline.")
to become "# Test scenario B: bot-only CR should not trigger stale pipeline."
and keep the rest unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 57d59f20-f3e5-4d54-aa2a-4576df83952d

📥 Commits

Reviewing files that changed from the base of the PR and between fab300c and c925729.

📒 Files selected for processing (2)
  • TEST_PR_668_B.md
  • bad_code_for_review.py
📜 Review details
🧰 Additional context used
🪛 Betterleaks (1.2.0)
bad_code_for_review.py

[high] 7-7: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data.

(stripe-access-token)

🪛 markdownlint-cli2 (0.22.1)
TEST_PR_668_B.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

Comment thread bad_code_for_review.py
Comment on lines +6 to +8
# Hardcoded credentials — should trigger a security flag.
API_KEY = "sk_live_4242424242424242"
DATABASE_PASSWORD = "admin123"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove committed secrets from source control.

This adds a Stripe-like live key and a plaintext database password to the repository. Move both to injected runtime configuration, and if either value was ever real, rotate it immediately.

🔐 Minimal fix
-# Hardcoded credentials — should trigger a security flag.
-API_KEY = "sk_live_4242424242424242"
-DATABASE_PASSWORD = "admin123"
+# Inject secrets at runtime instead of committing them.
+API_KEY = os.environ["API_KEY"]
+DATABASE_PASSWORD = os.environ["DATABASE_PASSWORD"]
🧰 Tools
🪛 Betterleaks (1.2.0)

[high] 7-7: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data.

(stripe-access-token)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bad_code_for_review.py` around lines 6 - 8, The file contains hardcoded
secrets in API_KEY and DATABASE_PASSWORD; remove these literals and read both
values from injected runtime configuration (e.g., environment variables or a
secrets/credentials provider) instead, update any initialization code that
references API_KEY or DATABASE_PASSWORD to fetch process/runtime config (e.g.,
os.environ or your config service) and fail fast with a clear error if missing,
purge the committed secrets from the repo history and rotate them if they were
ever real, and ensure you add guidance/docs or .env.example (without real
values) so developers know which keys to supply.

Comment thread bad_code_for_review.py
Comment on lines +11 to +13
def run_user_command(user_input):
# Command injection — passing user input to shell with shell=True.
return subprocess.check_output(user_input, shell=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Do not execute raw user input via a shell.

Passing untrusted input to subprocess.check_output(..., shell=True) is direct command injection. This needs an allowlisted command map and shell=False, not a raw shell entrypoint.

🛡️ Safer shape
+ALLOWED_COMMANDS = {
+    "list_tmp": ["ls", "/tmp"],
+}
+
-def run_user_command(user_input):
-    # Command injection — passing user input to shell with shell=True.
-    return subprocess.check_output(user_input, shell=True)
+def run_user_command(command_name):
+    return subprocess.check_output(ALLOWED_COMMANDS[command_name], shell=False)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bad_code_for_review.py` around lines 11 - 13, The run_user_command function
currently executes raw user input with subprocess.check_output(..., shell=True),
which allows command injection; replace this with an allowlisted command map and
call subprocess without shell (shell=False) using a list/sequence of arguments:
validate the user's requested command against an allowlist (e.g., a dict mapping
safe command names to fixed argument templates or executable paths), construct
the argv list deterministically (no string concatenation of user input), and
call subprocess.check_output(argv, shell=False); if the input is not
allowlisted, raise an error or return a safe failure response.

Comment thread bad_code_for_review.py
Comment on lines +16 to +19
def fetch_user(user_id):
# SQL injection — string concatenation into a query.
query = "SELECT * FROM users WHERE id = " + str(user_id)
return query
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop building tainted SQL strings.

Any caller that executes this returned query inherits SQL injection. Keep user data out of the SQL text and use bound parameters through the database driver instead of concatenation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bad_code_for_review.py` around lines 16 - 19, The fetch_user function
currently builds a tainted SQL string via concatenation; change it to use
parameterized queries/bound parameters instead of embedding user_id into the SQL
text. Replace the string concatenation in fetch_user with a SQL statement using
a placeholder (e.g., SELECT * FROM users WHERE id = ?) and return or execute
that statement with the user_id supplied as a separate parameter (or use your DB
driver's execute method with the query plus params). Ensure no user input is
interpolated into the SQL string in fetch_user to prevent SQL injection.

Comment thread bad_code_for_review.py
Comment on lines +22 to +24
def parse_config(data):
# eval on untrusted input.
return eval(data)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Replace eval with a real parser.

eval(data) is arbitrary code execution, and the __main__ path feeds raw stdin straight into it, so exploitation is one prompt away. Parse a constrained format instead of executing the input.

Also applies to: 34-35

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bad_code_for_review.py` around lines 22 - 24, The use of eval in
parse_config(data) is executing untrusted input; replace eval(data) with a
proper parser for a constrained format (e.g., json.loads or a strict YAML
parser) and validate the resulting structure, and make the same replacement for
the other occurrence referenced at lines 34-35; update the parse_config function
to return the parsed/validated dict and add input validation/error handling to
reject or sanitize unexpected types/fields.

Comment thread bad_code_for_review.py
Comment on lines +27 to +31
def bare_except():
try:
os.remove("/etc/passwd")
except:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Delete the destructive /etc/passwd removal path.

This helper attempts to remove a system file and then suppresses every failure. If it ever runs with elevated privileges, it can damage the host while hiding the incident from logs and callers.

🧹 Simplest fix
-def bare_except():
-    try:
-        os.remove("/etc/passwd")
-    except:
-        pass
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def bare_except():
try:
os.remove("/etc/passwd")
except:
pass
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bad_code_for_review.py` around lines 27 - 31, The function bare_except
contains a destructive call os.remove("/etc/passwd") and swallows all errors
with a bare except: pass; remove the hardcoded deletion immediately. If the
helper is meant to delete files, change bare_except to accept a validated path
parameter, validate against unsafe targets, call os.remove only on safe paths,
and replace the bare except with specific handlers (e.g., FileNotFoundError,
PermissionError) that either log the error or return a failure status instead of
silencing it; ensure you reference the bare_except function, the os.remove call,
and the bare except block when making the change.

Comment thread TEST_PR_668_B.md
@@ -0,0 +1 @@
Test scenario B: bot-only CR should not trigger stale pipeline.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use an H1 heading for the first line.

Line 1 should be a top-level markdown heading to satisfy MD041 and keep docs consistent.

Proposed fix
-Test scenario B: bot-only CR should not trigger stale pipeline.
+# Test scenario B: bot-only CR should not trigger stale pipeline
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Test scenario B: bot-only CR should not trigger stale pipeline.
# Test scenario B: bot-only CR should not trigger stale pipeline
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TEST_PR_668_B.md` at line 1, The first line of TEST_PR_668_B.md is not a
top-level heading; change Line 1 to an H1 markdown heading (prefix with "# ") so
the file begins with a single top-level heading to satisfy MD041 and doc
consistency; update the first line content ("Test scenario B: bot-only CR should
not trigger stale pipeline.") to become "# Test scenario B: bot-only CR should
not trigger stale pipeline." and keep the rest unchanged.

@Eeshu-Yadav
Copy link
Copy Markdown
Collaborator

Test PR for openwisp/openwisp-utils#668. All verifications complete; closing.

@Eeshu-Yadav-1 Eeshu-Yadav-1 deleted the test/pr-668-scenario-b-bot-only branch May 13, 2026 07:28
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.

3 participants