CTFs as you need them
This report summarizes scanner evidence for CTFd/CTFd, a Python project with 6,873 GitHub stars. SynthScan examined 94,478 lines of code across 746 source files, recording 949 pattern matches distributed across 14 syntactic categories. The legacy adjusted pattern signal is 13.9 (Moderate pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 849 finding(s).
Are imports declared and package/API names verified? 57 finding(s).
Are wrappers, guards, and repeated structures necessary? 672 finding(s).
Which changes need focused human review? 949 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 949 distinct pattern matches across 14 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_views.py | 153 | def test_pages_routing_and_rendering(): | CODE |
| LOW | tests/test_views.py | 181 | def test_user_can_access_files(): | CODE |
| LOW | tests/test_views.py | 276 | def test_admin_access_files_with_auth_token(): | CODE |
| LOW | tests/test_views.py | 351 | def test_user_can_access_files_with_auth_token(): | CODE |
| LOW | tests/test_views.py | 486 | def test_user_can_access_files_if_view_after_ctf(): | CODE |
| LOW⚡ | tests/test_themes.py | 18 | def test_themes_run_in_sandbox(): | CODE |
| LOW⚡ | tests/test_themes.py | 33 | def test_themes_cant_access_configpy_attributes(): | CODE |
| LOW | tests/test_themes.py | 81 | def test_that_ctfd_can_be_deployed_in_subdir(): | CODE |
| LOW | tests/test_themes.py | 125 | def test_that_ctfd_subdir_redirects_work(): | CODE |
| LOW | tests/test_themes.py | 159 | def test_that_request_path_hijacking_works_properly(): | CODE |
| LOW | tests/test_themes.py | 186 | def test_theme_fallback_config(): | CODE |
| LOW | tests/test_themes.py | 230 | def test_theme_template_loading_by_prefix(): | CODE |
| LOW | tests/test_themes.py | 239 | def test_theme_template_disallow_loading_admin_templates(): | CODE |
| LOW | tests/test_config.py | 19 | def test_reverse_proxy_config(): | CODE |
| LOW | tests/test_config.py | 59 | def test_server_sent_events_config(): | CODE |
| LOW | tests/test_config.py | 74 | def test_trusted_hosts_config(): | CODE |
| LOW | tests/test_config.py | 174 | def test_preset_admin_token_config(): | CODE |
| LOW | tests/test_config.py | 248 | def test_preset_admin_no_promotion_existing_user(): | CODE |
| LOW | tests/test_config.py | 334 | def test_preset_admin_empty_credentials(): | CODE |
| LOW | tests/test_plugin_utils.py | 29 | def test_register_plugin_asset(): | CODE |
| LOW | tests/test_plugin_utils.py | 42 | def test_register_plugin_assets_directory(): | CODE |
| LOW | tests/test_plugin_utils.py | 71 | def test_admin_override_template(): | CODE |
| LOW | tests/test_plugin_utils.py | 85 | def test_register_plugin_script(): | CODE |
| LOW | tests/test_plugin_utils.py | 99 | def test_register_plugin_stylesheet(): | CODE |
| LOW | tests/test_plugin_utils.py | 113 | def test_register_admin_plugin_script(): | CODE |
| LOW | tests/test_plugin_utils.py | 127 | def test_register_admin_plugin_stylesheet(): | CODE |
| LOW | tests/test_plugin_utils.py | 143 | def test_register_admin_plugin_menu_bar(): | CODE |
| LOW | tests/test_plugin_utils.py | 166 | def test_register_user_page_menu_bar(): | CODE |
| LOW | tests/test_plugin_utils.py | 190 | def test_bypass_csrf_protection(): | CODE |
| LOW | tests/test_plugin_utils.py | 202 | def bypass_csrf_protection_test_route(): | CODE |
| LOW | tests/test_plugin_utils.py | 218 | def test_challenges_model_access_plugin_class(): | CODE |
| LOW | tests/helpers.py | 640 | def gen_module_audience_access(db, module_id, audience_id): | CODE |
| LOW | tests/oauth/test_redirect.py | 15 | def test_oauth_not_configured(): | CODE |
| LOW | tests/oauth/test_redirect.py | 28 | def test_oauth_configured_flow(): | CODE |
| LOW | tests/oauth/test_users.py | 8 | def test_num_users_oauth_limit(): | CODE |
| LOW | tests/cache/test_challenges.py | 14 | def test_adding_challenge_clears_cache(): | CODE |
| LOW | tests/cache/test_challenges.py | 48 | def test_deleting_challenge_clears_cache_solves(): | CODE |
| LOW | tests/cache/test_challenges.py | 89 | def test_deleting_solve_clears_cache(): | CODE |
| LOW | tests/cache/test_cache.py | 43 | def test_clear_all_user_sessions(): | CODE |
| LOW | tests/cache/test_cache.py | 72 | def test_cache_subclass_commands(): | CODE |
| LOW | tests/cache/test_cache.py | 88 | def test_redis_cache_subclass_commands(): | CODE |
| LOW | tests/challenges/test_challenge_types.py | 8 | def test_missing_challenge_type(): | CODE |
| LOW | tests/challenges/test_challenge_logic.py | 15 | def test_all_flags_challenge_logic(): | CODE |
| LOW | tests/challenges/test_challenge_logic.py | 66 | def test_all_flags_challenge_logic_teams_mode(): | CODE |
| LOW | tests/challenges/test_challenge_logic.py | 145 | def test_group_flags_challenge_logic_teams_mode(): | CODE |
| LOW | tests/challenges/test_challenge_logic.py | 227 | def test_challenge_default_logic_is_any(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 18 | def test_can_create_standard_dynamic_challenge(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 53 | def test_can_update_standard_dynamic_challenge(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 101 | def test_can_add_requirement_standard_dynamic_challenge(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 159 | def test_can_delete_standard_dynamic_challenge(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 193 | def test_standard_dynamic_challenge_loses_value_properly(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 246 | def test_standard_dynamic_challenge_doesnt_lose_value_on_update(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 279 | def test_standard_dynamic_challenge_value_isnt_affected_by_hidden_users(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 339 | def test_standard_dynamic_challenges_reset(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 369 | def test_standard_dynamic_challenge_linear_loses_value_properly(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 421 | def test_standard_challenges_default_to_static_function(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 495 | def test_standard_dynamic_challenge_update_overrides_manual_value(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 593 | def test_standard_dynamic_challenge_creation_requires_all_parameters(): | CODE |
| LOW | tests/challenges/test_standard_dynamic.py | 732 | def test_dynamic_challenge_update_requires_all_parameters(): | CODE |
| LOW | tests/challenges/test_ratings.py | 19 | def test_ratings_public_config(): | CODE |
| 562 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | CTFd/auth.py | 20 | from CTFd.utils.helpers import error_for, get_errors, markup | CODE |
| CRITICAL | CTFd/scoreboard.py | 9 | from CTFd.utils.helpers import get_infos | CODE |
| CRITICAL | CTFd/users.py | 10 | from CTFd.utils.helpers import get_errors, get_infos | CODE |
| CRITICAL | CTFd/teams.py | 14 | from CTFd.utils.helpers import get_errors, get_infos | CODE |
| CRITICAL | CTFd/challenges.py | 13 | from CTFd.utils.helpers import get_errors, get_infos | CODE |
| CRITICAL | CTFd/views.py | 47 | from CTFd.utils.helpers import get_errors, get_infos, markup | CODE |
| CRITICAL | CTFd/constants/plugins.py | 4 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/constants/config.py | 34 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/constants/config.py | 40 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/constants/assets.py | 8 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/utils/decorators/__init__.py | 196 | from CTFd.utils.helpers import info_for | CODE |
| CRITICAL | CTFd/models/__init__.py | 70 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/models/__init__.py | 166 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/models/__init__.py | 173 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/models/__init__.py | 225 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/models/__init__.py | 327 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/models/__init__.py | 1085 | from CTFd.utils.helpers import markup | CODE |
| CRITICAL | CTFd/themes/admin/static/assets/htmlmixed-DvXcbxOJ.js | 19 | `);var m=document.activeElement;Kt(h),setTimeout(function(){r.display.lineSpace.removeChild(d),m.focus(),m==i&&n.showPri | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_config.py | 258 | # Create a regular user with the same credentials as preset admin | COMMENT |
| MEDIUM | tests/challenges/test_challenge_logic.py | 22 | # Create a challenge | COMMENT |
| MEDIUM | tests/challenges/test_challenge_logic.py | 73 | # Create a challenge with "all" logic | COMMENT |
| MEDIUM | tests/challenges/test_challenge_logic.py | 89 | # Create a team with members using gen_team helper | COMMENT |
| MEDIUM | tests/challenges/test_challenge_logic.py | 152 | # Create a challenge with "group" logic | COMMENT |
| MEDIUM | tests/challenges/test_challenge_logic.py | 168 | # Create a team with members using gen_team helper | COMMENT |
| MEDIUM | tests/challenges/test_challenge_logic.py | 234 | # Create a challenge without specifying logic (should default to "any") | COMMENT |
| MEDIUM | tests/challenges/test_standard_dynamic.py | 474 | # Create a user and solve the challenge | COMMENT |
| MEDIUM | tests/challenges/test_ratings.py | 236 | # Create a user and challenge | COMMENT |
| MEDIUM | tests/challenges/test_ratings.py | 275 | # Create a user and challenge | COMMENT |
| MEDIUM | tests/challenges/test_ratings.py | 355 | # Create a user and challenge | COMMENT |
| MEDIUM⚡ | tests/users/test_auth.py | 388 | # Create a user | COMMENT |
| MEDIUM⚡ | tests/users/test_auth.py | 792 | # Create a user before configuring mail to not send any extra emails | COMMENT |
| MEDIUM | tests/users/test_auth.py | 614 | # Create a user with change_password=True | COMMENT |
| MEDIUM | tests/users/test_auth.py | 720 | # Create a user via API with change_password=True | COMMENT |
| MEDIUM | tests/users/test_fields.py | 227 | # Create the fields that we want | COMMENT |
| MEDIUM | tests/teams/test_fields.py | 264 | # Create a user and team who haven't filled any of their fields | COMMENT |
| MEDIUM | tests/teams/test_teams.py | 163 | # Create a team with only one member | COMMENT |
| MEDIUM | tests/teams/test_teams.py | 198 | # Create a team | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 481 | # Create a challenge | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 615 | # Create a challenge and solution | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 625 | # Create a regular user | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 689 | # Create a hidden challenge and solution | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 699 | # Create a regular user | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 753 | # Create a challenge and solution with state="hidden" | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 763 | # Create a regular user | COMMENT |
| MEDIUM⚡ | tests/api/v1/test_solutions.py | 925 | # Create a user | COMMENT |
| MEDIUM | tests/api/v1/test_solutions.py | 533 | # Create a challenge and solution | COMMENT |
| MEDIUM | tests/api/v1/test_solutions.py | 544 | # Create a regular user | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 380 | # Create a user and generate a solve from before the freeze time | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 391 | # Create a user and generate a solve from after the freeze time | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 434 | # Create a banned user and generate a solve for the challenge | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 817 | # Create a user and generate a solve from before the freeze time | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 828 | # Create a user and generate a solve from after the freeze time | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 866 | # Create a user and generate a solve for the challenge | COMMENT |
| MEDIUM | tests/api/v1/test_challenges.py | 1480 | # Create a challenge and a user | COMMENT |
| MEDIUM | tests/api/v1/test_hints.py | 103 | # Create a challenge and two hints, where hint2 requires hint1 as a prerequisite | COMMENT |
| MEDIUM | tests/api/v1/test_files.py | 112 | # Create a fake file | COMMENT |
| MEDIUM | tests/api/v1/test_teams.py | 873 | # Create a user with a team | COMMENT |
| MEDIUM | tests/api/v1/test_scoreboard.py | 169 | # Create a challenge | COMMENT |
| MEDIUM | …ts/api/v1/challenges/requirements/test_requirements.py | 78 | # Create a new user which will solve the prerequisite | COMMENT |
| MEDIUM | …ts/api/v1/challenges/requirements/test_requirements.py | 106 | # Create a new user which will solve the prerequisite and hide them | COMMENT |
| MEDIUM | …ts/api/v1/challenges/requirements/test_requirements.py | 135 | # Create a new user which will solve the prerequisite and ban them | COMMENT |
| MEDIUM | …ts/api/v1/challenges/requirements/test_requirements.py | 241 | # Create a new user which will solve the prerequisite | COMMENT |
| MEDIUM | tests/api/v1/users/test_users.py | 62 | # Create a user with a null password. Use raw SQL to bypass SQLAlchemy validates | COMMENT |
| MEDIUM | tests/api/v1/teams/test_teams.py | 36 | # Create a user with a null password. Use raw SQL to bypass SQLAlchemy validates | COMMENT |
| MEDIUM | tests/api/v1/teams/test_teams.py | 80 | # Create a new team | COMMENT |
| MEDIUM | CTFd/views.py | 189 | # Create an empty index page | COMMENT |
| MEDIUM | CTFd/utils/security/auth.py | 50 | # Create the preset admin user | COMMENT |
| MEDIUM | CTFd/models/__init__.py | 789 | # Create the team specific secret | COMMENT |
| MEDIUM | CTFd/api/v1/helpers/models.py | 1 | # This file is no longer used. If you're importing the function from here please update your imports | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | populate.py | 285 | except Exception: | CODE |
| HIGH | populate.py | 488 | except Exception: | CODE |
| HIGH | tests/test_themes.py | 196 | except OSError: | CODE |
| HIGH | tests/test_themes.py | 26 | except SecurityError: | CODE |
| HIGH | tests/test_themes.py | 207 | except TemplateNotFound: | CODE |
| HIGH | tests/test_themes.py | 211 | except TemplateNotFound: | CODE |
| HIGH | tests/test_config.py | 92 | except SecurityError: | CODE |
| HIGH | tests/test_plugin_utils.py | 249 | except zipfile.BadZipfile: | CODE |
| HIGH | tests/utils/test_validators.py | 201 | except ValidationError: | CODE |
| HIGH | tests/teams/test_invites.py | 23 | except TeamTokenExpiredException: | CODE |
| HIGH | tests/teams/test_invites.py | 37 | except TeamTokenInvalidException: | CODE |
| HIGH | tests/api/test_tokens.py | 36 | except UserTokenExpiredException: | CODE |
| HIGH | tests/api/test_tokens.py | 44 | except UserNotFoundException: | CODE |
| HIGH | CTFd/config.py | 86 | except OSError: | CODE |
| HIGH | CTFd/admin/__init__.py | 207 | except ValueError: | CODE |
| HIGH | CTFd/utils/encoding/__init__.py | 13 | except UnicodeDecodeError: | CODE |
| HIGH | CTFd/utils/encoding/__init__.py | 22 | except UnicodeDecodeError: | CODE |
| HIGH | CTFd/utils/encoding/__init__.py | 34 | except UnicodeDecodeError: | CODE |
| HIGH | CTFd/utils/encoding/__init__.py | 46 | except UnicodeDecodeError: | CODE |
| HIGH | CTFd/utils/updates/__init__.py | 61 | except requests.exceptions.RequestException: | CODE |
| HIGH | CTFd/utils/updates/__init__.py | 63 | except ValueError: | CODE |
| HIGH | CTFd/utils/initialization/__init__.py | 181 | except IOError: | CODE |
| HIGH | CTFd/utils/exports/serializers.py | 53 | except ValueError: | CODE |
| HIGH | CTFd/utils/exports/serializers.py | 70 | except ValueError: | CODE |
| HIGH | CTFd/utils/exports/__init__.py | 376 | except (json.JSONDecodeError, TypeError): | CODE |
| HIGH | CTFd/api/v1/schemas/__init__.py | 28 | except KeyError: | CODE |
| HIGH | CTFd/api/v1/schemas/__init__.py | 52 | except KeyError: | CODE |
| HIGH | CTFd/api/v1/schemas/__init__.py | 97 | except KeyError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_views.py | 181 | CODE | |
| LOW | tests/test_views.py | 276 | CODE | |
| LOW | tests/test_views.py | 351 | CODE | |
| LOW | tests/test_views.py | 486 | CODE | |
| LOW | tests/helpers.py | 210 | CODE | |
| LOW | tests/helpers.py | 250 | CODE | |
| LOW | tests/helpers.py | 552 | CODE | |
| LOW | tests/challenges/test_standard_dynamic.py | 193 | CODE | |
| LOW | tests/challenges/test_standard_dynamic.py | 279 | CODE | |
| LOW | tests/challenges/test_standard_dynamic.py | 369 | CODE | |
| LOW | tests/challenges/test_standard_dynamic.py | 495 | CODE | |
| LOW | tests/challenges/test_dynamic.py | 184 | CODE | |
| LOW | tests/challenges/test_dynamic.py | 266 | CODE | |
| LOW | tests/challenges/test_dynamic.py | 354 | CODE | |
| LOW | tests/utils/test_exports.py | 127 | CODE | |
| LOW | tests/utils/test_uploaders.py | 178 | CODE | |
| LOW | tests/utils/test_uploaders.py | 213 | CODE | |
| LOW | tests/utils/test_ctftime.py | 28 | CODE | |
| LOW | tests/utils/test_ctftime.py | 53 | CODE | |
| LOW | tests/utils/test_ctftime.py | 90 | CODE | |
| LOW | tests/utils/test_ctftime.py | 118 | CODE | |
| LOW | tests/users/test_challenges.py | 402 | CODE | |
| LOW | tests/users/test_challenges.py | 591 | CODE | |
| LOW | tests/users/test_auth.py | 786 | CODE | |
| LOW | tests/users/test_fields.py | 54 | CODE | |
| LOW | tests/teams/test_fields.py | 60 | CODE | |
| LOW | tests/api/v1/test_solutions.py | 609 | CODE | |
| LOW | CTFd/auth.py | 237 | CODE | |
| LOW | CTFd/auth.py | 442 | CODE | |
| LOW | CTFd/auth.py | 547 | CODE | |
| LOW | CTFd/config.py | 24 | CODE | |
| LOW | CTFd/teams.py | 191 | CODE | |
| LOW | CTFd/views.py | 394 | CODE | |
| LOW | CTFd/plugins/challenges/logic.py | 72 | CODE | |
| LOW | CTFd/admin/__init__.py | 81 | CODE | |
| LOW | CTFd/admin/__init__.py | 222 | CODE | |
| LOW | CTFd/utils/__init__.py | 45 | CODE | |
| LOW | CTFd/utils/config/visibility.py | 22 | CODE | |
| LOW | CTFd/utils/decorators/__init__.py | 61 | CODE | |
| LOW | CTFd/utils/decorators/__init__.py | 195 | CODE | |
| LOW | CTFd/utils/decorators/__init__.py | 69 | CODE | |
| LOW | CTFd/utils/decorators/__init__.py | 199 | CODE | |
| LOW | CTFd/utils/decorators/visibility.py | 16 | CODE | |
| LOW | CTFd/utils/decorators/visibility.py | 55 | CODE | |
| LOW | CTFd/utils/decorators/visibility.py | 89 | CODE | |
| LOW | CTFd/utils/decorators/visibility.py | 18 | CODE | |
| LOW | CTFd/utils/decorators/visibility.py | 57 | CODE | |
| LOW | CTFd/utils/decorators/visibility.py | 91 | CODE | |
| LOW | CTFd/utils/plugins/__init__.py | 53 | CODE | |
| LOW | CTFd/utils/user/__init__.py | 18 | CODE | |
| LOW | CTFd/utils/updates/__init__.py | 15 | CODE | |
| LOW | CTFd/utils/initialization/__init__.py | 205 | CODE | |
| LOW | CTFd/utils/initialization/__init__.py | 313 | CODE | |
| LOW | CTFd/utils/exports/serializers.py | 38 | CODE | |
| LOW | CTFd/utils/exports/__init__.py | 121 | CODE | |
| LOW | CTFd/utils/exports/__init__.py | 302 | CODE | |
| LOW | CTFd/utils/csv/__init__.py | 477 | CODE | |
| LOW | CTFd/utils/events/__init__.py | 81 | CODE | |
| LOW | CTFd/utils/events/__init__.py | 83 | CODE | |
| LOW | CTFd/utils/helpers/models.py | 4 | CODE | |
| 16 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/__init__.py | 232 | CODE | |
| LOW | CTFd/plugins/dynamic_challenges/decay.py | 1 | CODE | |
| LOW | CTFd/plugins/challenges/decay.py | 1 | CODE | |
| LOW | CTFd/constants/config.py | 6 | CODE | |
| LOW | CTFd/constants/config.py | 6 | CODE | |
| LOW | CTFd/constants/config.py | 6 | CODE | |
| LOW | CTFd/constants/config.py | 6 | CODE | |
| LOW | CTFd/constants/config.py | 6 | CODE | |
| LOW | CTFd/constants/config.py | 6 | CODE | |
| LOW | CTFd/admin/__init__.py | 21 | CODE | |
| LOW | CTFd/admin/__init__.py | 22 | CODE | |
| LOW | CTFd/admin/__init__.py | 23 | CODE | |
| LOW | CTFd/admin/__init__.py | 24 | CODE | |
| LOW | CTFd/admin/__init__.py | 25 | CODE | |
| LOW | CTFd/admin/__init__.py | 26 | CODE | |
| LOW | CTFd/admin/__init__.py | 27 | CODE | |
| LOW | CTFd/admin/__init__.py | 28 | CODE | |
| LOW | CTFd/admin/__init__.py | 29 | CODE | |
| LOW | CTFd/admin/__init__.py | 30 | CODE | |
| LOW | CTFd/utils/security/signing.py | 6 | CODE | |
| LOW | CTFd/utils/security/signing.py | 6 | CODE | |
| LOW | CTFd/utils/security/signing.py | 6 | CODE | |
| LOW | CTFd/api/v1/statistics/__init__.py | 8 | CODE | |
| LOW | CTFd/api/v1/statistics/__init__.py | 9 | CODE | |
| LOW | CTFd/api/v1/statistics/__init__.py | 10 | CODE | |
| LOW | CTFd/api/v1/statistics/__init__.py | 11 | CODE | |
| LOW | CTFd/api/v1/statistics/__init__.py | 12 | CODE | |
| LOW | CTFd/api/v1/statistics/__init__.py | 13 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | populate.py | 467 | # Check if this user has already rated this challenge | COMMENT |
| LOW | tests/test_views.py | 306 | # Set CTF to start in the future (before CTF start scenario) | COMMENT |
| LOW⚡ | tests/users/test_auth.py | 381 | # Set CTFd to send emails | COMMENT |
| LOW⚡ | tests/users/test_auth.py | 795 | # Set CTFd to send emails | COMMENT |
| LOW | tests/users/test_auth.py | 328 | # Set CTFd to only allow confirmed users and send emails | COMMENT |
| LOW | tests/api/v1/user/test_hints.py | 190 | # Set challenges to be visible publicly | COMMENT |
| LOW | tests/api/v1/user/test_hints.py | 236 | # Set challenges to be visible to only authed | COMMENT |
| LOW | CTFd/auth.py | 454 | # Check if credentials match preset admin | COMMENT |
| LOW | CTFd/auth.py | 468 | # Check if the user submitted an email address or a team name | COMMENT |
| LOW | CTFd/auth.py | 604 | # Check if we are allowing registration before creating users | COMMENT |
| LOW | CTFd/views.py | 266 | # Set theme to default and try again | COMMENT |
| LOW | CTFd/plugins/migrations.py | 66 | # Check if the plugin has migraitons | COMMENT |
| LOW | CTFd/plugins/challenges/logic.py | 84 | # Check if the user's submission is correct | COMMENT |
| LOW | CTFd/admin/users.py | 90 | # Check if the user has an account (team or user) | COMMENT |
| LOW | CTFd/utils/security/auth.py | 41 | # Check if user already exists | COMMENT |
| LOW | CTFd/utils/user/__init__.py | 22 | # Check if the session is still valid | COMMENT |
| LOW | CTFd/utils/exports/__init__.py | 182 | # Check if the alembic version is from CTFd 1.x | COMMENT |
| LOW | CTFd/api/v1/challenges.py | 199 | # Iterate through the list of challenges, adding to the object which | COMMENT |
| LOW | CTFd/api/v1/challenges.py | 1258 | # Check if challenge is visible to the user | COMMENT |
| LOW | CTFd/api/v1/challenges.py | 1265 | # Check if user/team has solved this challenge (only allow rating if solved) | COMMENT |
| LOW | CTFd/api/v1/challenges.py | 1351 | # Check if challenge is visible to the user | COMMENT |
| LOW | CTFd/api/v1/helpers/request.py | 39 | # Check if the schema is for enums, if so, we just add in the "enum" key | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | requirements.txt | 1 | # This file was autogenerated by uv via the following command: | COMMENT |
| LOW | requirements.txt | 21 | boto3==1.35.27 | COMMENT |
| LOW | requirements.txt | 41 | cmarkgfm==2024.11.20 | COMMENT |
| LOW | requirements.txt | 61 | flask-caching==2.3.1 | COMMENT |
| LOW | requirements.txt | 81 | # gevent | COMMENT |
| LOW | requirements.txt | 101 | # via flask-restx | COMMENT |
| LOW | requirements.txt | 121 | # ctfd | COMMENT |
| LOW | requirements.txt | 141 | python-dotenv==0.13.0 | COMMENT |
| LOW | requirements.txt | 161 | s3transfer==0.10.4 | COMMENT |
| LOW | requirements.txt | 181 | # via ctfd | COMMENT |
| LOW | tests/utils/test_validators.py | 161 | COMMENT | |
| LOW | tests/utils/test_events.py | 221 | # "team": None, | COMMENT |
| LOW | tests/utils/test_events.py | 241 | # data=saved_event["data"], type="notification", channel="ctf" | COMMENT |
| LOW | tests/users/test_challenges.py | 81 | # with app.app_context(): | COMMENT |
| LOW | tests/users/test_challenges.py | 101 | # with client.session_transaction() as sess: | COMMENT |
| LOW | CTFd/config.ini | 1 | # CTFd Configuration File | COMMENT |
| LOW | CTFd/config.ini | 21 | # | COMMENT |
| LOW | CTFd/config.ini | 61 | # REDIS_URL | COMMENT |
| LOW | CTFd/config.ini | 101 | # Comma seperated string containing valid host names for CTFd to respond to. If not specified, | COMMENT |
| LOW | CTFd/config.ini | 161 | # MAILSENDER_ADDR | COMMENT |
| LOW | CTFd/config.ini | 181 | # By default CTFd will automatically detect the correct email provider based on the other settings | COMMENT |
| LOW | CTFd/config.ini | 201 | # AWS secret token used to authenticate to the S3 bucket. Only used under the s3 uploader. | COMMENT |
| LOW | CTFd/config.ini | 221 | COMMENT | |
| LOW | CTFd/config.ini | 241 | # See https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#werkzeug.middleware.proxy_fix.ProxyFix. | COMMENT |
| LOW | CTFd/config.ini | 261 | # SWAGGER_UI | COMMENT |
| LOW | CTFd/config.ini | 281 | # Defaults to true | COMMENT |
| LOW | CTFd/config.ini | 301 | # EMAIL_CONFIRMATION_REQUIRE_INTERACTION | COMMENT |
| LOW | CTFd/config.ini | 321 | # PRESET_ADMIN_NAME | COMMENT |
| LOW | CTFd/config.ini | 341 | # Configuration values that will be loaded into CTFd and take precedence over database settings. | COMMENT |
| LOW | CTFd/utils/validators/__init__.py | 21 | # Remove any leading and trailing C0 control or space from input. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/api/v1/test_solutions.py | 930 | # Step 1: Before solving, user queries the challenge detail endpoint | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 940 | # Step 2: Check the challenge solution endpoint - should also return no solution_id | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 948 | # Step 3: User attempts to view the solution directly - should fail (404 for hidden solutions) | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 952 | # Step 4: User solves the challenge | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 962 | # Step 5: After solving, user queries the challenge detail endpoint again | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 972 | # Step 6: User queries the challenge solution endpoint - should now return solution_id | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 980 | # Step 7: User tries to view the solution - should see it but content is locked (not unlocked yet) | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1004 | # Step 9: Verify the unlock was recorded in the database | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1012 | # Step 10: User views the solution again - now they should see the full content | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1023 | # Step 12: Create another user who has NOT solved the challenge | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1028 | # Step 13: Other user queries the challenge detail endpoint | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1037 | # Step 14: Other user queries the solution endpoint directly | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1046 | # Step 15: Other user tries to view the solution directly | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1051 | # Step 16: Other user attempts to unlock the solution | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1059 | # Step 17: Verify no unlock was recorded for the other user | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1065 | # Step 18: Other user tries to view the solution again | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1083 | # Step 19: Other user now solves the challenge | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1093 | # Step 20: After solving, other user should now see the solution_id | COMMENT |
| LOW | tests/api/v1/test_solutions.py | 992 | # Step 8: User unlocks the solution via the unlock API | COMMENT |
| LOW | tests/api/v1/test_solutions.py | 1112 | # Step 21: Other user can now view the solution with full content | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/api/v1/test_solutions.py | 930 | # Step 1: Before solving, user queries the challenge detail endpoint | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 940 | # Step 2: Check the challenge solution endpoint - should also return no solution_id | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 948 | # Step 3: User attempts to view the solution directly - should fail (404 for hidden solutions) | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 952 | # Step 4: User solves the challenge | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 962 | # Step 5: After solving, user queries the challenge detail endpoint again | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 972 | # Step 6: User queries the challenge solution endpoint - should now return solution_id | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 980 | # Step 7: User tries to view the solution - should see it but content is locked (not unlocked yet) | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1004 | # Step 9: Verify the unlock was recorded in the database | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1012 | # Step 10: User views the solution again - now they should see the full content | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1023 | # Step 12: Create another user who has NOT solved the challenge | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1028 | # Step 13: Other user queries the challenge detail endpoint | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1037 | # Step 14: Other user queries the solution endpoint directly | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1046 | # Step 15: Other user tries to view the solution directly | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1051 | # Step 16: Other user attempts to unlock the solution | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1059 | # Step 17: Verify no unlock was recorded for the other user | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1065 | # Step 18: Other user tries to view the solution again | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1083 | # Step 19: Other user now solves the challenge | COMMENT |
| LOW⚡ | tests/api/v1/test_solutions.py | 1093 | # Step 20: After solving, other user should now see the solution_id | COMMENT |
| LOW | tests/api/v1/test_solutions.py | 992 | # Step 8: User unlocks the solution via the unlock API | COMMENT |
| LOW | tests/api/v1/test_solutions.py | 1112 | # Step 21: Other user can now view the solution with full content | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | populate.py | 285 | except Exception: | CODE |
| LOW | populate.py | 488 | except Exception: | CODE |
| LOW | ping.py | 30 | except Exception as e: | CODE |
| LOW⚡ | tests/test_themes.py | 28 | except Exception as e: | CODE |
| LOW | tests/api/test_tokens.py | 38 | except Exception as e: | CODE |
| LOW | tests/api/test_tokens.py | 46 | except Exception as e: | CODE |
| LOW | CTFd/views.py | 282 | except Exception: | CODE |
| LOW | CTFd/utils/initialization/__init__.py | 362 | except Exception: | CODE |
| LOW | CTFd/utils/exports/__init__.py | 176 | except Exception: | CODE |
| LOW | CTFd/utils/exports/__init__.py | 264 | except Exception: | CODE |
| LOW | CTFd/utils/exports/__init__.py | 487 | except Exception: | CODE |
| LOW | CTFd/utils/sessions/__init__.py | 87 | except Exception: | CODE |
| LOW | CTFd/utils/email/providers/smtp.py | 74 | except Exception as e: | CODE |
| LOW | CTFd/cli/__init__.py | 84 | except Exception as e: | CODE |
| MEDIUM | CTFd/cli/__init__.py | 81 | def import_ctf(path, delete_import_on_finish=False): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/helpers.py | 129 | CODE | |
| LOW | CTFd/plugins/challenges/__init__.py | 141 | CODE | |
| LOW | CTFd/utils/__init__.py | 28 | CODE | |
| LOW | CTFd/utils/challenges/__init__.py | 131 | CODE | |
| LOW | CTFd/utils/user/__init__.py | 98 | CODE | |
| LOW | CTFd/utils/user/__init__.py | 132 | CODE | |
| LOW | CTFd/utils/exports/serializers.py | 36 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | CTFd/utils/security/sanitize.py | 40 | "input": ["name", "type", "value", "placeholder"], | CODE |
| LOW⚡ | CTFd/utils/security/sanitize.py | 41 | "select": ["name", "value", "placeholder"], | CODE |
| LOW⚡ | CTFd/utils/security/sanitize.py | 43 | "textarea": ["name", "value", "placeholder"], | CODE |
| LOW | …hemes/admin/static/assets/pages/statistics-8IMWcF-M.js | 1 | import{_ as A,C as h,c,a as t,t as u,h as m,l as v,F as g,r as f,w as p,j as y,v as I,d as C,o as d,i as S,N as U,$ as k | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | CTFd/api/v1/helpers/request.py | 39 | # Check if the schema is for enums, if so, we just add in the "enum" key | COMMENT |