-
-
Notifications
You must be signed in to change notification settings - Fork 313
Command injection Lab #4504
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
Command injection Lab #4504
Conversation
WalkthroughAdds a Django management command that idempotently creates/updates a "Command Injection" lab with eight tasks and TaskContent records; adds a command-injection-specific payload label and textarea to task_detail; makes a whitespace-only comment edit in Simulation.html. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as Management Command
participant DB as Database (Lab, Task, TaskContent)
CLI->>DB: get_or_create Lab "Command Injection"
alt Lab created
DB-->>CLI: new Lab
else Lab exists
DB-->>CLI: existing Lab
end
loop for each task (1..8)
CLI->>DB: update_or_create Task (lab, order) -> set metadata
CLI->>DB: update_or_create TaskContent -> set theory OR simulation_config
DB-->>CLI: Task/TaskContent created or updated
end
CLI->>DB: call Lab.update_total_tasks() if present
DB-->>CLI: confirmation
note right of CLI: CLI prints per-item created/updated counts
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Assessment against linked issues
Out-of-scope changes
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
✨ Finishing Touches🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
website/templates/task_detail.html (1)
126-144: Fix unreachable nested conditions and restore CSRF-specific UI label/placeholderThe inner {% if/elif %} chain inside the SQL Injection branch is unreachable for non-SQL labs, causing the CSRF-specific label/placeholder never to render. This is a regression and will show the generic label for CSRF instead of the intended “Enter your CSRF attack code:”.
Simplify the SQL branch and add a dedicated CSRF branch alongside XSS/Command Injection to remove duplication and make behavior correct/predictable.
Apply this diff:
{% if lab.name == "SQL Injection" %} - <label for="payload" class="block text-sm font-medium text-gray-700 mb-2"> - {% if lab.name == "SQL Injection" %} - Enter your SQL injection payload: - {% elif lab.name == "Cross-Site Scripting (XSS)" %} - Enter your XSS payload: - {% elif lab.name == "Cross-Site Request Forgery" %} - Enter your CSRF attack code: - {% elif lab.name == "Command Injection" %} - Enter your command injection payload: - {% else %} - Enter your payload: - {% endif %} - </label> + <label for="payload" class="block text-sm font-medium text-gray-700 mb-2">Enter your SQL injection payload:</label> <textarea id="payload" name="payload" rows="4" class="shadow-sm focus:ring-[#e74c3c] focus:border-[#e74c3c] mt-1 block w-full sm:text-sm border border-gray-300 rounded-md p-3" - placeholder="{% if lab.name == 'SQL Injection' %}Enter your SQL injection payload here...{% elif lab.name == 'Cross-Site Scripting (XSS)' %}Enter your XSS payload here...{% elif lab.name == 'Cross-Site Request Forgery' %}Enter your CSRF attack code here...{% else %}Enter your payload here...{% endif %}"></textarea> + placeholder="Enter your SQL injection payload here... (e.g., ' OR 1=1--)"></textarea> {% elif lab.name == "Cross-Site Scripting (XSS)" %} <label for="payload" class="block text-sm font-medium text-gray-700 mb-2">Enter your XSS payload:</label> <textarea id="payload" name="payload" rows="4" class="shadow-sm focus:ring-[#e74c3c] focus:border-[#e74c3c] mt-1 block w-full sm:text-sm border border-gray-300 rounded-md p-3" placeholder="Enter your XSS payload here... (e.g., <script>alert('XSS')</script>)"></textarea> +{% elif lab.name == "Cross-Site Request Forgery" %} + <label for="payload" class="block text-sm font-medium text-gray-700 mb-2">Enter your CSRF attack code:</label> + <textarea id="payload" + name="payload" + rows="4" + class="shadow-sm focus:ring-[#e74c3c] focus:border-[#e74c3c] mt-1 block w-full sm:text-sm border border-gray-300 rounded-md p-3" + placeholder="Enter your CSRF attack code here..."></textarea>
🧹 Nitpick comments (4)
website/templates/task_detail.html (1)
152-158: Minor UX: make payload textarea monospaced and disable autocorrectPayloads are code-like; a monospace font reduces errors and improves readability. Disabling autocorrect/capitalization/spellcheck avoids unintended mutations on mobile.
Apply this diff:
- <textarea id="payload" + <textarea id="payload" name="payload" rows="4" - class="shadow-sm focus:ring-[#e74c3c] focus:border-[#e74c3c] mt-1 block w-full sm:text-sm border border-gray-300 rounded-md p-3" - placeholder="Enter your command injection payload here... (e.g., 127.0.0.1; ls)"></textarea> + class="shadow-sm focus:ring-[#e74c3c] focus:border-[#e74c3c] mt-1 block w-full sm:text-sm border border-gray-300 rounded-md p-3 font-mono" + spellcheck="false" autocapitalize="off" inputmode="text" + placeholder="Enter your command injection payload here... (e.g., 127.0.0.1; ls)"></textarea>website/management/commands/create_commands_injection_tasks.py (3)
1-1: Make the management command atomic to avoid partial updatesIf an exception occurs midway (e.g., while creating content for task 5), you’ll end up with a partially-seeded lab. Wrap
handlein a transaction.Apply this diff:
from django.core.management.base import BaseCommand +from django.db import transaction @@ -class Command(BaseCommand): +class Command(BaseCommand): help = "Create Command Injection lab tasks" - def handle(self, *args, **options): + @transaction.atomic + def handle(self, *args, **options):
10-23: Ensure existing Lab metadata is updated on rerunsCurrently, when the lab already exists, description/difficulty/is_active aren’t updated. This can leave stale data if content evolves. Update fields when
createdis False.Apply this diff:
- command_injection_lab, created = Labs.objects.get_or_create( - name="Command Injection", - defaults={ - "description": "Learn about command injection vulnerabilities and how to exploit them", - "difficulty": "Intermediate", - "is_active": True, - }, - ) + lab_defaults = { + "description": "Learn about command injection vulnerabilities and how to exploit them", + "difficulty": "Intermediate", + "is_active": True, + } + command_injection_lab, created = Labs.objects.get_or_create( + name="Command Injection", + defaults=lab_defaults, + ) @@ - else: - self.stdout.write(self.style.WARNING(f"Lab already exists: {command_injection_lab.name}")) + else: + # Keep lab metadata in sync across reruns + for field, value in lab_defaults.items(): + setattr(command_injection_lab, field, value) + command_injection_lab.save(update_fields=list(lab_defaults.keys())) + self.stdout.write(self.style.WARNING(f"Lab already exists (updated): {command_injection_lab.name}"))
215-219: Fallback ifupdate_total_tasksis absentYou already guard with
hasattr. For completeness, consider a fallback to setlab.total_tasks = Tasks.objects.filter(lab=lab, is_active=True).count()to keep counts consistent even if the method is missing.Here’s a minimal, guarded fallback:
- if hasattr(command_injection_lab, "update_total_tasks"): - command_injection_lab.update_total_tasks() + if hasattr(command_injection_lab, "update_total_tasks"): + command_injection_lab.update_total_tasks() + else: + try: + total = Tasks.objects.filter(lab=command_injection_lab, is_active=True).count() + setattr(command_injection_lab, "total_tasks", total) + command_injection_lab.save(update_fields=["total_tasks"]) + except Exception: + # Silently ignore if the field does not exist + pass
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (2)
website/management/commands/create_commands_injection_tasks.py(1 hunks)website/templates/task_detail.html(2 hunks)
🔇 Additional comments (4)
website/management/commands/create_commands_injection_tasks.py (4)
24-169: Content structure and idempotency look goodThe
tasks_datadesign is clear, and usingupdate_or_createper (lab, order) ensures idempotent runs. The MCQ options align with the template’soption.0usage andcorrect_answervalues (“A”, “B”, etc.). Nicely done.
171-214: Good use ofupdate_or_createfor tasks and contentThe idempotent pattern across tasks and their content reduces operational footguns when re-running the command. Clear console messages also help during seeding.
193-195: TaskContent.mcq_options correctly uses JSONFieldThe
mcq_optionsfield onTaskContentis already defined asmcq_options = models.JSONField(default=list, blank=True)which natively supports storing Python lists. No changes are required.
141-145: Action Required: Verify Shell Execution Context for Simulation TasksI did not find any invocation of subprocess.run (or similar) with
shell=True, nor any use ofos.systemorshlexin the repository. This suggests that command‐injection simulation tasks may not be executed in a POSIX shell environment—and therefore constructs like${IFS}and&&would not be interpreted.• Please locate and review the simulation engine’s execution logic to confirm whether it invokes a real shell (e.g. with
shell=True).
• If it does not, either update the engine to support these shell features or adjust the success payloads to avoid relying on${IFS}parameter expansion and shell‐specific operators (e.g. use simple separators or multiple payloads).
Fixes: #4493
Summary by CodeRabbit
New Features
Style