Review ID: d909e04ee655Generated: 2026-04-09T16:39:08.356Z
CHANGES REQUESTED
218
Total Findings
1
Critical
7
Medium
209
Low
6 Tools Deployed
DiamondPlatinumGoldSilverBronzeHR RoastyFree Baseline
Free Baseline Scan — Open-source tools + HRPE
HeroHours-main →
AIAI Threat Analysis
Loading AI analysis...
218 raw scanner findings — 1 critical · 7 medium · 209 low · 1 info
Raw Scanner Output — 218 pre-cleanup findings
⚠ Pre-Cleanup Report
This is the raw, unprocessed output from all scanner agents before AI analysis. Do not use this to fix issues individually. Multiple agents attack from different angles and frequently report the same underlying vulnerability, resulting in significant duplication. Architectural issues also appear as many separate line-level findings when they require a single structural fix.

Use the Copy Fix Workflow button above to get the AI-cleaned workflow — it deduplicates findings, removes false positives, and provides actionable steps. This raw output is provided for transparency and audit purposes only.
MEDIUM[F401] 'datetime.datetime' imported but unused
[redacted]/graph_meetings.py:2
[AGENTS: baseline:flake8]code_quality
'datetime.datetime' imported but unused
MEDIUM[F401] 'django.db.models.F' imported but unused
[redacted]/0018_activitylog_user.py:5
[AGENTS: baseline:flake8]code_quality
'django.db.models.F' imported but unused
MEDIUM[F401] 'django.test.TestCase' imported but unused
[redacted]/tests.py:1
[AGENTS: baseline:flake8]code_quality
'django.test.TestCase' imported but unused
MEDIUM[F401] 'django.contrib.admin' imported but unused
[redacted]/admin.py:1
[AGENTS: baseline:flake8]code_quality
'django.contrib.admin' imported but unused
MEDIUM[F401] 'django.db.models' imported but unused
[redacted]/models.py:1
[AGENTS: baseline:flake8]code_quality
'django.db.models' imported but unused
MEDIUM[F401] 'django.test.TestCase' imported but unused
[redacted]/tests.py:1
[AGENTS: baseline:flake8]code_quality
'django.test.TestCase' imported but unused
MEDIUM[semgrep] python.django.security.django-no-csrf-token.django-no-csrf-token
[redacted]/index.html:37
[AGENTS: baseline:semgrep]security
Manually-created forms in django templates should specify a csrf_token to prevent CSRF attacks.
LOW[W391] blank line at end of file
[redacted]/__init__.py:1
[AGENTS: baseline:flake8]code_quality
blank line at end of file
LOW[E302] expected 2 blank lines, found 1
[redacted]/admin.py:32
[AGENTS: baseline:flake8]code_quality
expected 2 blank lines, found 1
LOW[E501] line too long (91 > 79 characters)
[redacted]/admin.py:48
[AGENTS: baseline:flake8]code_quality
line too long (91 > 79 characters)
LOW[E501] line too long (99 > 79 characters)
[redacted]/admin.py:50
[AGENTS: baseline:flake8]code_quality
line too long (99 > 79 characters)
LOW[E501] line too long (111 > 79 characters)
[redacted]/admin.py:54
[AGENTS: baseline:flake8]code_quality
line too long (111 > 79 characters)
LOW[E302] expected 2 blank lines, found 1
[redacted]/admin.py:78
[AGENTS: baseline:flake8]code_quality
expected 2 blank lines, found 1
LOW[E501] line too long (122 > 79 characters)
[redacted]/admin.py:105
[AGENTS: baseline:flake8]code_quality
line too long (122 > 79 characters)
LOW[E302] expected 2 blank lines, found 1
[redacted]/admin.py:108
[AGENTS: baseline:flake8]code_quality
expected 2 blank lines, found 1
LOW[E501] line too long (120 > 79 characters)
[redacted]/admin.py:114
[AGENTS: baseline:flake8]code_quality
line too long (120 > 79 characters)
LOW[E231] missing whitespace after ':'
[redacted]/admin.py:138
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E231] missing whitespace after ':'
[redacted]/admin.py:139
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E231] missing whitespace after ':'
[redacted]/admin.py:140
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E231] missing whitespace after ':'
[redacted]/admin.py:141
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E231] missing whitespace after ':'
[redacted]/admin.py:142
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E231] missing whitespace after ':'
[redacted]/admin.py:143
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E501] line too long (107 > 79 characters)
[redacted]/admin.py:173
[AGENTS: baseline:flake8]code_quality
line too long (107 > 79 characters)
LOW[E501] line too long (83 > 79 characters)
[redacted]/admin.py:176
[AGENTS: baseline:flake8]code_quality
line too long (83 > 79 characters)
LOW[E303] too many blank lines (2)
[redacted]/admin.py:185
[AGENTS: baseline:flake8]code_quality
too many blank lines (2)
LOW[W293] blank line contains whitespace
[redacted]/admin.py:187
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[W293] blank line contains whitespace
[redacted]/admin.py:190
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (88 > 79 characters)
[redacted]/admin.py:191
[AGENTS: baseline:flake8]code_quality
line too long (88 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/admin.py:193
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (85 > 79 characters)
[redacted]/admin.py:194
[AGENTS: baseline:flake8]code_quality
line too long (85 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/admin.py:196
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (80 > 79 characters)
[redacted]/admin.py:197
[AGENTS: baseline:flake8]code_quality
line too long (80 > 79 characters)
LOW[E501] line too long (82 > 79 characters)
[redacted]/admin.py:198
[AGENTS: baseline:flake8]code_quality
line too long (82 > 79 characters)
LOW[E501] line too long (83 > 79 characters)
[redacted]/admin.py:199
[AGENTS: baseline:flake8]code_quality
line too long (83 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/admin.py:200
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (87 > 79 characters)
[redacted]/admin.py:201
[AGENTS: baseline:flake8]code_quality
line too long (87 > 79 characters)
LOW[E501] line too long (80 > 79 characters)
[redacted]/admin.py:202
[AGENTS: baseline:flake8]code_quality
line too long (80 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/admin.py:204
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (87 > 79 characters)
[redacted]/admin.py:205
[AGENTS: baseline:flake8]code_quality
line too long (87 > 79 characters)
LOW[E501] line too long (85 > 79 characters)
[redacted]/admin.py:206
[AGENTS: baseline:flake8]code_quality
line too long (85 > 79 characters)
LOW[E501] line too long (87 > 79 characters)
[redacted]/admin.py:208
[AGENTS: baseline:flake8]code_quality
line too long (87 > 79 characters)
LOW[E501] line too long (86 > 79 characters)
[redacted]/admin.py:209
[AGENTS: baseline:flake8]code_quality
line too long (86 > 79 characters)
LOW[E501] line too long (84 > 79 characters)
[redacted]/admin.py:210
[AGENTS: baseline:flake8]code_quality
line too long (84 > 79 characters)
LOW[E501] line too long (86 > 79 characters)
[redacted]/admin.py:211
[AGENTS: baseline:flake8]code_quality
line too long (86 > 79 characters)
LOW[E501] line too long (85 > 79 characters)
[redacted]/admin.py:213
[AGENTS: baseline:flake8]code_quality
line too long (85 > 79 characters)
LOW[E261] at least two spaces before inline comment
[redacted]/admin.py:234
[AGENTS: baseline:flake8]code_quality
at least two spaces before inline comment
LOW[E261] at least two spaces before inline comment
[redacted]/admin.py:235
[AGENTS: baseline:flake8]code_quality
at least two spaces before inline comment
LOW[E501] line too long (86 > 79 characters)
[redacted]/admin.py:267
[AGENTS: baseline:flake8]code_quality
line too long (86 > 79 characters)
LOW[E501] line too long (105 > 79 characters)
[redacted]/admin.py:276
[AGENTS: baseline:flake8]code_quality
line too long (105 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/admin.py:283
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (81 > 79 characters)
[redacted]/admin.py:335
[AGENTS: baseline:flake8]code_quality
line too long (81 > 79 characters)
LOW[W391] blank line at end of file
[redacted]/admin.py:339
[AGENTS: baseline:flake8]code_quality
blank line at end of file
LOW[E501] line too long (84 > 79 characters)
[redacted]/consumers.py:3
[AGENTS: baseline:flake8]code_quality
line too long (84 > 79 characters)
LOW[E501] line too long (109 > 79 characters)
[redacted]/consumers.py:20
[AGENTS: baseline:flake8]code_quality
line too long (109 > 79 characters)
LOW[E501] line too long (108 > 79 characters)
[redacted]/consumers.py:23
[AGENTS: baseline:flake8]code_quality
line too long (108 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/consumers.py:26
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (85 > 79 characters)
[redacted]/consumers.py:27
[AGENTS: baseline:flake8]code_quality
line too long (85 > 79 characters)
LOW[E231] missing whitespace after ','
[redacted]/consumers.py:30
[AGENTS: baseline:flake8]code_quality
missing whitespace after ','
LOW[W293] blank line contains whitespace
[redacted]/consumers.py:44
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E231] missing whitespace after ':'
[redacted]/consumers.py:50
[AGENTS: baseline:flake8]code_quality
missing whitespace after ':'
LOW[E501] line too long (85 > 79 characters)
[redacted]/consumers.py:53
[AGENTS: baseline:flake8]code_quality
line too long (85 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/consumers.py:56
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[W293] blank line contains whitespace
[redacted]/consumers.py:59
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[W293] blank line contains whitespace
[redacted]/consumers.py:63
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[W293] blank line contains whitespace
[redacted]/consumers.py:77
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[W391] blank line at end of file
[redacted]/consumers.py:82
[AGENTS: baseline:flake8]code_quality
blank line at end of file
LOW[E301] expected 1 blank line, found 0
[redacted]/forms.py:10
[AGENTS: baseline:flake8]code_quality
expected 1 blank line, found 0
LOW[E501] line too long (82 > 79 characters)
[redacted]/forms.py:12
[AGENTS: baseline:flake8]code_quality
line too long (82 > 79 characters)
LOW[E501] line too long (94 > 79 characters)
[redacted]/forms.py:13
[AGENTS: baseline:flake8]code_quality
line too long (94 > 79 characters)
LOW[E501] line too long (89 > 79 characters)
[redacted]/forms.py:14
[AGENTS: baseline:flake8]code_quality
line too long (89 > 79 characters)
LOW[E501] line too long (90 > 79 characters)
[redacted]/forms.py:16
[AGENTS: baseline:flake8]code_quality
line too long (90 > 79 characters)
LOW[W391] blank line at end of file
[redacted]/__init__.py:1
[AGENTS: baseline:flake8]code_quality
blank line at end of file
LOW[W391] blank line at end of file
[redacted]/__init__.py:1
[AGENTS: baseline:flake8]code_quality
blank line at end of file
LOW[E302] expected 2 blank lines, found 1
[redacted]/bulk.py:5
[AGENTS: baseline:flake8]code_quality
expected 2 blank lines, found 1
LOW[E111] indentation is not a multiple of 4
[redacted]/bulk.py:9
[AGENTS: baseline:flake8]code_quality
indentation is not a multiple of 4
LOW[E111] indentation is not a multiple of 4
[redacted]/bulk.py:10
[AGENTS: baseline:flake8]code_quality
indentation is not a multiple of 4
LOW[E501] line too long (93 > 79 characters)
[redacted]/bulk.py:20
[AGENTS: baseline:flake8]code_quality
line too long (93 > 79 characters)
LOW[W293] blank line contains whitespace
[redacted]/bulk.py:21
[AGENTS: baseline:flake8]code_quality
blank line contains whitespace
LOW[E501] line too long (91 > 79 characters)
[redacted]/graph_meetings.py:4
[AGENTS: baseline:flake8]code_quality
line too long (91 > 79 characters)
LOW[E302] expected 2 blank lines, found 1
[redacted]/graph_meetings.py:6
[AGENTS: baseline:flake8]code_quality
expected 2 blank lines, found 1
LOW[E301] expected 1 blank line, found 0
[redacted]/graph_meetings.py:8
[AGENTS: baseline:flake8]code_quality
expected 1 blank line, found 0
LOW[E501] line too long (123 > 79 characters)
[redacted]/graph_meetings.py:25
[AGENTS: baseline:flake8]code_quality
line too long (123 > 79 characters)
LOW[E501] line too long (111 > 79 characters)
[redacted]/graph_meetings.py:28
[AGENTS: baseline:flake8]code_quality
line too long (111 > 79 characters)
LOW[E501] line too long (124 > 79 characters)
[redacted]/graph_meetings.py:38
[AGENTS: baseline:flake8]code_quality
line too long (124 > 79 characters)
LOW[E501] line too long (97 > 79 characters)
[redacted]/graph_meetings.py:43
[AGENTS: baseline:flake8]code_quality
line too long (97 > 79 characters)
LOW[E501] line too long (98 > 79 characters)
[redacted]/graph_meetings.py:44
[AGENTS: baseline:flake8]code_quality
line too long (98 > 79 characters)
LOW[E501] line too long (98 > 79 characters)
[redacted]/graph_meetings.py:51
[AGENTS: baseline:flake8]code_quality
line too long (98 > 79 characters)
LOW[E501] line too long (81 > 79 characters)
[redacted]/import_users.py:3
[AGENTS: baseline:flake8]code_quality
line too long (81 > 79 characters)
LOW[E302] expected 2 blank lines, found 1
[redacted]/import_users.py:5
[AGENTS: baseline:flake8]code_quality
expected 2 blank lines, found 1
LOW[E111] indentation is not a multiple of 4
[redacted]/import_users.py:9
[AGENTS: baseline:flake8]code_quality
indentation is not a multiple of 4
LOW[E501] line too long (88 > 79 characters)
[redacted]/import_users.py:23
[AGENTS: baseline:flake8]code_quality
line too long (88 > 79 characters)
LOW[E501] line too long (80 > 79 characters)
[redacted]/import_users.py:30
[AGENTS: baseline:flake8]code_quality
line too long (80 > 79 characters)
LOW[E501] line too long (84 > 79 characters)
[redacted]/0001_initial.py:17
[AGENTS: baseline:flake8]code_quality
line too long (84 > 79 characters)
LOW[E501] line too long (117 > 79 characters)
[redacted]/0008_activitylog_alter_users_total_hours.py:16
[AGENTS: baseline:flake8]code_quality
line too long (117 > 79 characters)
LOW[E501] line too long (125 > 79 characters)
[redacted]/0008_activitylog_alter_users_total_hours.py:18
[AGENTS: baseline:flake8]code_quality
line too long (125 > 79 characters)
LOW[E501] line too long (113 > 79 characters)
[redacted]/0008_activitylog_alter_users_total_hours.py:19
[AGENTS: baseline:flake8]code_quality
line too long (113 > 79 characters)
LOW[E501] line too long (104 > 79 characters)
[redacted]/0011_alter_activitylog_options_alter_activitylog_status.py:20
[AGENTS: baseline:flake8]code_quality
line too long (104 > 79 characters)
LOW[E501] line too long (81 > 79 characters)
[redacted]/0012_alter_activitylog_options_alter_users_options_and_more.py:9
[AGENTS: baseline:flake8]code_quality
line too long (81 > 79 characters)
LOW[E501] line too long (82 > 79 characters)
[redacted]/0012_alter_activitylog_options_alter_users_options_and_more.py:19
[AGENTS: baseline:flake8]code_quality
line too long (82 > 79 characters)
LOW[E501] line too long (130 > 79 characters)
[redacted]/0012_alter_activitylog_options_alter_users_options_and_more.py:24
[AGENTS: baseline:flake8]code_quality
line too long (130 > 79 characters)

Summary

## SECURITY CODE REVIEW ANALYSIS ### CRITICAL FINDINGS **1. Hardcoded API Key Exposure** - **Location**: `HeroHours_api/authentication.py:45` - **Issue**: Generic API key detected in authentication logic - **Root Cause**: Token-based authentication implementation that could expose sensitive keys - **Real-World Impact**: Attackers could extract API keys from source code or version control, leading to unauthorized access, data breaches, and account takeover - **Fix**: ```python # Remove hardcoded keys and use environment variables import os from django.conf import settings class URLTokenAuthentication(BaseAuthentication): def authenticate_credentials(self, key): # Validate against stored tokens, not hardcoded values model = self.get_model() try: token = model.objects.select_related('user').get(key=key) except model.DoesNotExist: raise exceptions.AuthenticationFailed(_('Invalid token.')) ``` ### MEDIUM SEVERITY FINDINGS **1. Missing CSRF Protection in Django Template** - **Location**: `templates/index.html:37` - **Issue**: Manually-created form without CSRF token - **Root Cause**: Form submission vulnerability to Cross-Site Request Forgery - **Real-World Impact**: Attackers could trick authenticated users into performing unwanted actions (changing settings, deleting data) - **Fix**: ```html <form method="post"> {% csrf_token %} <!-- form fields --> </form> ``` **2. Unused Imports (Multiple Locations)** - **Locations**: - `HeroHours/management/commands/graph_meetings.py:2` - `HeroHours/migrations/0018_activitylog_user.py:5` - `HeroHours/tests.py:1` - `HeroHours_api/admin.py:1` - `HeroHours_api/models.py:1` - `HeroHours_api/tests.py:1` - **Root Cause**: Development artifacts and incomplete refactoring - **Impact**: Code bloat, potential security issues if unused code contains vulnerabilities, maintenance complexity - **Fix**: Remove all unused imports and clean up dead code ### LOW SEVERITY FINDINGS **1. Code Style Violations (Multiple)** - **Locations**: Various lines in `HeroHours/admin.py` - **Issues**: - Line length violations (79+ characters) - Whitespace inconsistencies - Missing blank lines - Trailing whitespace - **Root Cause**: Inconsistent coding standards - **Impact**: Reduced code readability, potential merge conflicts, difficulty in code review - **Fix**: Apply consistent PEP 8 styling, use black/isort for formatting **2. Empty/Incomplete Files** - **Locations**: Multiple `__init__.py` and empty serializers - **Issue**: Placeholder files with no functionality - **Impact**: Confusion about module structure, potential for misuse - **Fix**: Either implement proper functionality or remove unnecessary files ### ARCHITECTURAL OBSERVATIONS **Authentication Design Issues:** 1. **Custom URL Token Authentication** appears to be a modified version of DRF's TokenAuthentication but with URL parameters instead of headers 2. **Security Concern**: URL parameters are logged in server logs, browser history, and referrer headers 3. **Better Approach**: Use standard Authorization headers or secure HTTP-only cookies **Code Organization Issues:** 1. **Duplicate App Structure**: Both `HeroHours` and `HeroHours_api` apps exist with similar structures 2. **Mixed Concerns**: Admin configurations mixed with business logic in `admin.py` 3. **Missing Tests**: Test files exist but contain no actual tests --- ## BEYOND PATTERN MATCHING: AI-DETECTABLE ARCHITECTURAL ISSUES **1. Authentication Flow Vulnerability** - **What AI Would Catch**: The `URLTokenAuthentication` class uses URL parameters for tokens, which violates OWASP recommendations. Tokens in URLs are exposed in logs, analytics, and browser history. - **Traditional Tools Miss**: They only see "token" strings but don't understand the architectural implications. - **AI Insight**: "You're implementing token auth but putting tokens in URLs. This is like writing passwords on sticky notes. Move to Authorization headers or secure cookies." **2. Business Logic in Admin Interface** - **What AI Would Catch**: `HeroHours/admin.py` contains complex business logic (lines 138-143 show hardcoded mappings) that should be in models or services. - **Traditional Tools Miss**: They see style violations but not the architectural anti-pattern. - **AI Insight**: "Admin interfaces should be thin wrappers over models, not contain business rules. This creates security gaps where admin changes bypass validation." **3. Incomplete API Layer** - **What AI Would Catch**: `HeroHours_api/serializers.py` is empty while authentication exists, suggesting an incomplete API implementation that could have inconsistent security. - **Traditional Tools Miss**: Empty files don't trigger security alerts. - **AI Insight**: "You have authentication without serializers. This suggests endpoints might bypass validation entirely, creating data injection vulnerabilities." **4. Missing Rate Limiting** - **What AI Would Catch**: No visible rate limiting on the URL token authentication, making brute-force attacks trivial. - **Traditional Tools Miss**: Can't detect missing security controls. - **AI Insight**: "Token endpoints without rate limiting are like having a lock but leaving the key under the mat. Attackers can try every key." **5. Data Flow Analysis Gap** - **What AI Would Catch**: The `get_authorization_key` function handles both string and bytes inconsistently, potentially causing encoding issues that could bypass validation. - **Traditional Tools Miss**: They see encoding operations but not the security implications. - **AI Insight**: "Mixed string/bytes handling in auth can lead to encoding bypass attacks where 'admin' and 'admin%00' are treated differently." ### RECOMMENDED ACTION PLAN 1. **Immediate (Critical)**: - Remove hardcoded authentication logic - Implement CSRF tokens in all forms - Move tokens from URLs to Authorization headers 2. **Short-term (Medium)**: - Clean up unused imports and dead code - Implement proper serializers for API endpoints - Add rate limiting to authentication endpoints 3. **Long-term (Architectural)**: - Separate business logic from admin interfaces - Implement consistent error handling - Add comprehensive test coverage - Consider using Django REST Framework's built-in authentication classes The most concerning issue is the custom authentication implementation that exposes tokens in URLs. This should be addressed immediately as it represents a clear security vulnerability that could lead to account compromise.

Note: Fixing issues can create a domino effect — resolving one finding often surfaces new ones that were previously hidden. Multiple scan-and-fix cycles may be needed until you’re satisfied no further issues remain. How deep you go is your call.