Skip to content

Bugs/improvements/security issues #79

@cktang88

Description

@cktang88

From codex:

Critical — Security Vulnerabilities

1. Shell injection via OAuth URL

  • File: src/auth/oauth.ts:53
  • Passes unsanitized URL to exec(). A crafted URL can execute arbitrary shell commands.
  • Fix: Use execFile() or child_process.spawn() instead.

2. Plaintext credential storage

  • File: src/auth/credentials.ts
  • API keys and OAuth tokens are stored as unencrypted JSON in ~/.mmx/.
  • One cat command = full account takeover.
  • Fix: Use OS keychain integration (keytar, security on macOS).

3. Insecure file permissions are warnings, not errors

  • File: src/auth/credentials.ts:39-50
  • Detects 0o644 on credential files, logs a warning, and continues.
  • On shared systems, tokens are readable by other users.
  • Fix: Refuse to load credentials with insecure permissions.

High — Silent Failures & Data Corruption

4. Streaming errors silently swallowed

  • File: src/commands/text/chat.ts:194
  • SSE parse errors are caught and dropped. Output is silently corrupted mid-stream with no indication to the user.

5. Concurrent token refresh corrupts credentials

  • File: src/auth/credentials.ts, src/auth/refresh.ts
  • Two parallel mmx invocations both read the same refresh token, both call the token endpoint, one invalidates the other's.
  • Fix: File locking on credential read/write.

6. Network truncation goes undetected

  • File: src/files/download.ts:17
  • Defaults contentLength to 0 when header is missing. Never compares received bytes vs expected. User gets a truncated file and thinks it succeeded.

7. Polling discards API failure context

  • File: src/polling/poll.ts:35-40
  • Throws 'Task failed.' with zero detail from the API response. Users cannot diagnose why video/music generation failed.

8. Corrupted credentials return null silently

  • File: src/auth/credentials.ts:15-21
  • JSON parse errors on the credentials file return null with a stderr warning. Non-interactive callers get silent auth failure.

High — Crash Bugs (Unhandled Exceptions)

9. Non-null assertion on API audio data

  • File: src/output/audio.ts:23
  • response.data.audio! — null/undefined audio = runtime crash. Odd-length hex string = Buffer.from throws.

10. Base64 memory bomb

  • File: src/commands/vision/describe.ts:29-35
  • Reads entire image into memory via arrayBuffer() with no size limit. 500MB image = OOM kill.

11. Tool JSON parsing has no error handling

  • File: src/commands/text/chat.ts:136-145
  • Tries JSON.parse, falls back to readFileSync. Missing file or invalid JSON = uncaught exception.

12. Disk full during file write

  • Files: src/output/audio.ts, src/files/download.ts
  • Neither writeFileSync nor createWriteStream handles ENOSPC. Partial corrupt files left behind.

Medium — Correctness Bugs

13. File ID heuristic is wrong

  • File: src/commands/vision/describe.ts:76-77
  • Uses "no dot and not http" to detect file IDs. UUIDs, filenames with dashes, dotless filenames all misclassified.

14. Voice language filter is too greedy

  • File: src/commands/speech/voices.ts:18
  • Case-insensitive substring match means --language ch matches Chinese, Czech, and Icelandic. No "no results found" feedback.

15. Region detection falls back silently

  • File: src/config/detect-region.ts:10-21
  • Probes quota endpoint. If a CN-only key fails the global probe, defaults to 'global' — user gets cryptic errors on every subsequent command.

16. File overwrite without warning

  • File: src/commands/image/generate.ts:152-163
  • Silently overwrites existing files. Batch failures leave partial state with no rollback.

17. --output json ignored in quiet mode

  • File: src/commands/image/generate.ts:165-167
  • Dumps raw file paths even when user requested JSON output.

Medium — Missing Validation

18. No flag value validation anywhere

  • Flag parsing accepts anything: --timeout abc becomes NaN, --region invalid passes through, --max-tokens 999999999 is unchecked. Crashes happen downstream, not at the boundary.

19. No request timeout on token refresh

  • File: src/auth/refresh.ts
  • HTTP call with no timeout. Unresponsive server = CLI hangs forever.

20. No request timeout on polling

  • File: src/polling/poll.ts
  • requestJson() calls during task status checks have no per-request timeout.

21. No size validation before base64 encoding

  • File: src/commands/image/generate.ts:122-125
  • Reads reference image with readFileSync and base64-encodes without file size check.

22. SSE stream never validates content-type

  • File: src/client/stream.ts
  • Assumes response body is text SSE. HTML error pages are parsed as SSE, producing garbage output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions