Skip to content

fix(security): resolve P0 code scanning alerts — potential bug + false positive suppressions #803

Description

@manavgup

Problem

5 open code scanning alerts that should be fixed immediately. None are active vulnerabilities but one is a potential bug and the rest need explicit suppression to keep the alert list clean.

Alerts

1. Implicit string concatenation — potential bug (#189)

File: src/wikimind/engine/qa_agent.py:174-176
Rule: CodeQL py/implicit-string-concatenation-in-list
Risk: Adjacent string literals in a list are implicitly concatenated. Could mask a missing comma.

Fix: Wrap the multi-line string in parentheses to make intent explicit:

# Before (lines 174-176):
"You also have access to external tools. If the wiki context is insufficient, "
"you MAY suggest calling one of these tools by including a 'tool_calls' array "
"in your response:",

# After:
(
    "You also have access to external tools. If the wiki context is insufficient, "
    "you MAY suggest calling one of these tools by including a 'tool_calls' array "
    "in your response:"
),

2. Empty except — WebSocket disconnect (#55)

File: src/wikimind/api/routes/ws.py:271
Rule: CodeQL py/empty-except

Fix: Add explanatory comment:

except WebSocketDisconnect:
    pass  # Expected during normal client disconnect; cleanup in finally

3. Empty except — storage read (#54)

File: src/wikimind/engine/concept_compiler.py:73
Rule: CodeQL py/empty-except

Fix: Add debug logging:

except (OSError, ValueError):
    log.debug("skipped article content", article_id=article.id, reason="storage read failed")

4. XML ParseError import — false positive (#149, #133)

File: src/wikimind/ingest/adapters/rss.py:11,29
Rule: Bandit B405
Context: Actual XML parsing already uses defusedxml.ElementTree. Only the ParseError exception class is imported from stdlib xml.etree.ElementTree (defusedxml doesn't re-export it).

Fix: Add inline suppression:

from xml.etree.ElementTree import ParseError  # nosec B405 -- exception class only, parsing uses defusedxml

5. Insecure random — false positive (#1, #2)

File: src/wikimind/engine/linter/contradictions.py:428,438
Rule: Bandit B311
Context: random.sample() is used for performance down-sampling of article pairs, not for any security/cryptographic purpose.

Fix: Add inline suppression:

sampled = random.sample(pairs, max_pairs)  # nosec B311 -- sampling for performance, not security

Acceptance Criteria

  • All 5 alerts resolved or suppressed
  • make verify passes
  • No new alerts introduced

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendPython / FastAPI / gatewaybugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions