Skip to content

Normalize OWASP cheat sheet references - #954

Open
Bornunique911 wants to merge 5 commits into
OWASP:mainfrom
Bornunique911:review/issue-471-cheatsheet-references-clean
Open

Normalize OWASP cheat sheet references#954
Bornunique911 wants to merge 5 commits into
OWASP:mainfrom
Bornunique911:review/issue-471-cheatsheet-references-clean

Conversation

@Bornunique911

@Bornunique911 Bornunique911 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR is split out from the larger issue-471 review flow to make review smaller and more focused.

It normalizes OWASP cheat sheet references by:

  • using official OWASP Cheat Sheet Series links
  • adding supplemental cheat sheet mappings for references that are not reliably discoverable from repository parsing alone
  • covering that behavior with focused parser tests

Issue reference:

Problem Fixed

The earlier cheat sheet references review became too large because it was mixed with unrelated importer-stack work.

For this part of the work, the useful standalone contribution is:

  • using official cheat sheet URLs
  • supplementing missing cheat sheet references with explicit mapping data
  • ensuring parser behavior remains test-covered

Solution

This PR updates the cheat sheet parser to:

  • tolerate repository clone failure and continue with supplemental cheat sheet mappings
  • load supplemental cheat sheet mapping data from JSON
  • deduplicate cheat sheet entries by section and hyperlink
  • keep official OWASP Cheat Sheet Series hyperlinks for normalized references

This PR also adds:

  • supplemental cheat sheet mapping data
  • focused parser test coverage for the supplemental references

Files in scope:

  • application/utils/external_project_parsers/parsers/cheatsheets_parser.py
  • application/utils/external_project_parsers/data/owasp_cheatsheets_supplement.json
  • application/tests/cheatsheets_parser_test.py

Tests

./venv/bin/python -m pytest application/tests/cheatsheets_parser_test.py -q

Reviewer Notes

This PR is intentionally narrow because it was split to reduce review size:

  • no frontend changes
  • no unrelated OWASP importer modules
  • no refresh script aggregation
  • no bundle artifacts

This PR is meant to be reviewed as a standalone cheat sheet reference normalization change.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: dc56e50f-ab8e-4b45-a537-f66fc85013d8

📥 Commits

Reviewing files that changed from the base of the PR and between 700c75e and c3346fc.

📒 Files selected for processing (1)
  • application/tests/cheatsheets_parser_test.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • application/tests/cheatsheets_parser_test.py

Summary by CodeRabbit

  • New Features

    • Added supplemental OWASP cheat sheet coverage for nine security topics.
    • Added REST security cheat sheet support and related metadata.
    • Cheat sheets now link directly to official OWASP pages.
  • Bug Fixes

    • Cheat sheet results remain available when the external repository cannot be cloned.
    • Duplicate entries are merged while preserving all associated CRE references.
    • Improved result matching across multiple cheat sheet sections for more accurate links and metadata.

Walkthrough

This PR updates the OWASP cheat sheet parser to combine repository entries with supplemental metadata. It generates official OWASP HTML URLs, handles clone failures, creates CRE links, and merges duplicate entries.

Changes

Cheat sheet registration and supplemental linking

Layer / File(s) Summary
Official cheat sheet URLs and registration
application/utils/external_project_parsers/parsers/cheatsheets_parser.py, application/tests/cheatsheets_parser_test.py
Repository entries now use official OWASP HTML URLs. Tests validate the updated hyperlink, link type, tags, section matching, and fixture filename.
Supplemental metadata and CRE links
application/utils/external_project_parsers/data/owasp_cheatsheets_supplement.json, application/utils/external_project_parsers/parsers/cheatsheets_parser.py, application/tests/cheatsheets_parser_test.py
Supplemental records define nine cheat sheet topics and CRE ranges. The parser loads these records and creates automatic CRE links. Tests validate REST metadata and linked CRE documents.
Fallback and duplicate consolidation
application/utils/external_project_parsers/parsers/cheatsheets_parser.py, application/tests/cheatsheets_parser_test.py
Clone failures no longer prevent supplemental entries from loading. Duplicate entries merge their unique CRE links. Tests cover both behaviors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: northdpole, pa04rth, paoga87

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary change: normalizing OWASP cheat sheet references.
Description check ✅ Passed The description directly explains the parser changes, supplemental mappings, deduplication, clone-failure handling, and focused tests.
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.
✨ 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.

@Bornunique911
Bornunique911 force-pushed the review/issue-471-cheatsheet-references-clean branch from 7f640f4 to aac9e3b Compare July 7, 2026 12:23
@Bornunique911
Bornunique911 force-pushed the review/issue-471-cheatsheet-references-clean branch from aac9e3b to 79cab23 Compare July 26, 2026 13:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
application/tests/cheatsheets_parser_test.py (1)

81-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover clone fallback and duplicate merging.

The new test covers supplemental loading only. Add cases where git.clone fails but a seeded supplemental entry is still returned, and where repository/supplement entries share (section, hyperlink) and their CRE links are merged. This protects both new parse paths.

🤖 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 `@application/tests/cheatsheets_parser_test.py` around lines 81 - 102, Add test
cases alongside test_register_supplemental_cheatsheets covering clone failure
with a seeded supplemental entry still returned, and repository/supplement
entries sharing the same (section, hyperlink) with their CRE links merged.
Configure the git.clone failure through the existing test seam and assert both
fallback retention and deduplicated combined links.
🤖 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 `@application/utils/external_project_parsers/parsers/cheatsheets_parser.py`:
- Around line 57-61: Restrict the exception handler around the OWASP
CheatSheetSeries clone in the parser to expected process and OS failures raised
by git.clone(), such as subprocess and operating-system errors. Do not catch
arbitrary Exception, so parser and configuration defects propagate normally
while the existing warning and supplemental-cheat-sheets fallback remain
unchanged for those failures.

---

Nitpick comments:
In `@application/tests/cheatsheets_parser_test.py`:
- Around line 81-102: Add test cases alongside
test_register_supplemental_cheatsheets covering clone failure with a seeded
supplemental entry still returned, and repository/supplement entries sharing the
same (section, hyperlink) with their CRE links merged. Configure the git.clone
failure through the existing test seam and assert both fallback retention and
deduplicated combined links.
🪄 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: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: d61289eb-2550-49a5-9d56-a8af8cd692f9

📥 Commits

Reviewing files that changed from the base of the PR and between 8fe46df and 79cab23.

📒 Files selected for processing (3)
  • application/tests/cheatsheets_parser_test.py
  • application/utils/external_project_parsers/data/owasp_cheatsheets_supplement.json
  • application/utils/external_project_parsers/parsers/cheatsheets_parser.py

Comment thread application/utils/external_project_parsers/parsers/cheatsheets_parser.py Outdated
@Bornunique911
Bornunique911 force-pushed the review/issue-471-cheatsheet-references-clean branch from cc87a19 to 5d5b850 Compare July 31, 2026 19:21
@Bornunique911
Bornunique911 force-pushed the review/issue-471-cheatsheet-references-clean branch from 5d5b850 to f8912f9 Compare August 4, 2026 16:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
application/tests/cheatsheets_parser_test.py (2)

93-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use next(...) for single-match lookups.

These comprehensions allocate a list only to retrieve its first item. Use next(...) to resolve Ruff RUF015.

Proposed change
-        rest = [
-            entry for entry in entries if entry.section == "REST Security Cheat Sheet"
-        ][0]
+        rest = next(
+            entry
+            for entry in entries
+            if entry.section == "REST Security Cheat Sheet"
+        )
...
-        rest = [
-            node
-            for node in entries.results["OWASP Cheat Sheets"]
-            if node.section == "REST Security Cheat Sheet"
-        ][0]
+        rest = next(
+            node
+            for node in entries.results["OWASP Cheat Sheets"]
+            if node.section == "REST Security Cheat Sheet"
+        )

Also applies to: 125-129

🤖 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 `@application/tests/cheatsheets_parser_test.py` around lines 93 - 95, Update
the single-match lookups in the test around the `rest` assignment and the
additional occurrence at the referenced location to use `next(...)` over the
filtered generator instead of building a list and indexing `[0]`, resolving Ruff
RUF015 while preserving the existing match behavior.

Source: Linters/SAST tools


100-103: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert the supplemental link type.

register_supplemental_cheatsheets in application/utils/external_project_parsers/parsers/cheatsheets_parser.py (Lines 108-140) creates AutomaticallyLinkedTo links. This test only checks document IDs, so a different link type would pass.

Proposed change
         self.assertEqual(
             ["118-110", "724-770", "623-550"],
             [link.document.id for link in rest.links],
         )
+        self.assertEqual(
+            [defs.LinkTypes.AutomaticallyLinkedTo] * 3,
+            [link.ltype for link in rest.links],
+        )
🤖 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 `@application/tests/cheatsheets_parser_test.py` around lines 100 - 103, The
test assertion at lines 100-103 only validates the document IDs from rest.links
but does not verify the link type. Add an assertion that checks each link in
rest.links is of the expected type (AutomaticallyLinkedTo) to ensure the
register_supplemental_cheatsheets parser is creating the correct link type, not
just returning the correct document IDs.
🤖 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 `@application/tests/cheatsheets_parser_test.py`:
- Line 149: Replace the tempfile.mkdtemp() usage in the affected test with a
tempfile.TemporaryDirectory context or managed instance, ensuring the temporary
repository directory is automatically cleaned up after the test while preserving
the existing loc path usage.

In `@application/utils/external_project_parsers/parsers/cheatsheets_parser.py`:
- Around line 130-139: The link-building handler around cre.shallow_copy() and
cs.add_link() must not suppress unexpected programming errors. Restrict the
except block to the specific expected link-validation exception(s), allowing all
other exceptions to propagate, while preserving the existing warning and
add_link_failures behavior for expected failures.

---

Nitpick comments:
In `@application/tests/cheatsheets_parser_test.py`:
- Around line 93-95: Update the single-match lookups in the test around the
`rest` assignment and the additional occurrence at the referenced location to
use `next(...)` over the filtered generator instead of building a list and
indexing `[0]`, resolving Ruff RUF015 while preserving the existing match
behavior.
- Around line 100-103: The test assertion at lines 100-103 only validates the
document IDs from rest.links but does not verify the link type. Add an assertion
that checks each link in rest.links is of the expected type
(AutomaticallyLinkedTo) to ensure the register_supplemental_cheatsheets parser
is creating the correct link type, not just returning the correct document IDs.
🪄 Autofix

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: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8aa1024b-27a6-463c-9173-f1f6a971f6cf

📥 Commits

Reviewing files that changed from the base of the PR and between 79cab23 and f8912f9.

📒 Files selected for processing (3)
  • application/tests/cheatsheets_parser_test.py
  • application/utils/external_project_parsers/data/owasp_cheatsheets_supplement.json
  • application/utils/external_project_parsers/parsers/cheatsheets_parser.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • application/utils/external_project_parsers/data/owasp_cheatsheets_supplement.json

Comment thread application/tests/cheatsheets_parser_test.py Outdated
Comment thread application/utils/external_project_parsers/parsers/cheatsheets_parser.py Outdated
…heatsheets parser

- Replace `tempfile.mkdtemp()` with `tempfile.TemporaryDirectory` + `addCleanup`
  in `test_parse_merges_repo_and_supplemental_duplicate_entries` to ensure
  automatic cleanup of temporary repository directory.

- Narrow exception handling in `register_supplemental_cheatsheets` to catch only
  `ValueError` for expected link‑validation errors, allowing unexpected
  programming errors to propagate.

- Convert list‑index lookups (`[...][0]`) to `next()` over generators in
  `test_register_supplemental_cheatsheets` and
  `test_parse_returns_supplemental_entries_when_clone_fails` (RUF015).

- Add assertion in `test_register_supplemental_cheatsheets` to verify that all
  links are of type `AutomaticallyLinkedTo`, ensuring correct link type
  creation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
application/tests/cheatsheets_parser_test.py (2)

118-125: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Verify that the clone-failure path runs.

mock_clone.side_effect only affects the test when git.clone is called. Without a call assertion, parse() could skip cloning and still return the supplemental entry. Add mock_clone.assert_called() after parse().

Proposed test assertion
         entries = cheatsheets_parser.Cheatsheets().parse(
             cache=self.collection, ph=PromptHandler(database=self.collection)
         )
+        mock_clone.assert_called()
🤖 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 `@application/tests/cheatsheets_parser_test.py` around lines 118 - 125, Add a
call assertion immediately after the Cheatsheets().parse invocation to verify
mock_clone was called, ensuring the test exercises the clone-failure path rather
than passing without cloning.

67-80: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Require a non-empty parser result.

If entries.results is empty, the loop at Line 67 does not execute. The test then passes without checking the registration. Assert that parser.name is present and inspect that result directly.

Proposed test assertion
-        for name, nodes in entries.results.items():
-            self.assertEqual(name, parser.name)
+        self.assertIn(parser.name, entries.results)
+        nodes = entries.results[parser.name]
🤖 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 `@application/tests/cheatsheets_parser_test.py` around lines 67 - 80, Update
the test around parser.name and entries.results to assert that parser.name is
present before inspecting its nodes, rather than relying on the for loop to
execute. Retrieve the result for parser.name directly and keep the existing
section and expected secret_entry assertions against that result, ensuring an
empty registration fails the test.
🤖 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.

Outside diff comments:
In `@application/tests/cheatsheets_parser_test.py`:
- Around line 118-125: Add a call assertion immediately after the
Cheatsheets().parse invocation to verify mock_clone was called, ensuring the
test exercises the clone-failure path rather than passing without cloning.
- Around line 67-80: Update the test around parser.name and entries.results to
assert that parser.name is present before inspecting its nodes, rather than
relying on the for loop to execute. Retrieve the result for parser.name directly
and keep the existing section and expected secret_entry assertions against that
result, ensuring an empty registration fails the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3198380c-4c17-4ae3-8514-19c44b679c0c

📥 Commits

Reviewing files that changed from the base of the PR and between f8912f9 and 700c75e.

📒 Files selected for processing (2)
  • application/tests/cheatsheets_parser_test.py
  • application/utils/external_project_parsers/parsers/cheatsheets_parser.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • application/utils/external_project_parsers/parsers/cheatsheets_parser.py

- Replace `tempfile.mkdtemp()` with `tempfile.TemporaryDirectory` + `addCleanup`
  in `test_parse_merges_repo_and_supplemental_duplicate_entries` to ensure
  automatic cleanup of temporary repository directory.

- Narrow exception handling in `register_supplemental_cheatsheets` to catch only
  `ValueError` for expected link‑validation errors, allowing unexpected
  programming errors to propagate.

- Convert list‑index lookups (`[...][0]`) to `next()` over generators in
  `test_register_supplemental_cheatsheets` and
  `test_parse_returns_supplemental_entries_when_clone_fails` (RUF015).

- Add assertion in `test_register_supplemental_cheatsheets` to verify that all
  links are of type `AutomaticallyLinkedTo`, ensuring correct link type
  creation.

- In `test_parse_returns_supplemental_entries_when_clone_fails`, add
  `mock_clone.assert_called_once()` to verify the clone-failure path is
  exercised.

- In `test_register_cheatsheet`, replace the `for`-loop over `entries.results`
  with a direct lookup of `parser.name`, ensuring the test fails explicitly when
  `entries.results` is empty rather than silently passing.
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.

1 participant