Skip to content

Conversation

FDiskas
Copy link

@FDiskas FDiskas commented Aug 20, 2025

vibe coded PR

closes #1321

This PR fixes a security vulnerability where unescaped characters in OpenAPI/Swagger descriptions could break generated TypeScript files or enable code injection attacks. The fix uses minimal escaping - only escaping the dangerous */ sequences while leaving harmless /* sequences unescaped to reduce noise in generated documentation.

Problem

Vulnerable input example:

description: "This endpoint is equivalent to **/information** endpoint"
summary: "Get data with **/ alert('XSS') /** injection attempt"

Generated vulnerable output:

/**
 * Description with */ alert('XSS') /* injection attempt
 */

The */ sequence breaks out of the JSDoc comment, allowing arbitrary JavaScript code execution.

Solution

The fix applies surgical escaping that only targets the dangerous pattern:

  • */ sequences are escaped to *\/ (prevents comment breakout)
  • /* sequences remain unescaped (harmless inside comments)

Safe output after fix:

/**
 * Description with *\/ alert('XSS') /* injection attempt
 */

Technical Details

  • Core changes: Updated escapeJSDocContent() in src/schema-parser/schema-formatters.ts to only escape */
  • Template consistency: Modified route-docs.ejs to use consistent escaping approach
  • Smart detection: formatDescription() detects already-escaped content to prevent double-escaping
  • Fixed snapshots: Corrected test snapshots to show proper single backslash escaping

Impact

  • Security: Prevents code injection through OpenAPI documentation fields
  • Clean output: Reduces unnecessary escaping noise (no more \/* in docs)
  • Compatibility: No breaking changes to existing functionality

Copilot AI and others added 8 commits August 20, 2025 18:29
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
- Modified formatDescription() to detect already-escaped content and avoid double-escaping
- Ensures */  becomes *\/ (single backslash) instead of *\\/ (double backslash)
- Ensures /*  becomes \/* (single backslash) instead of \\/* (double backslash)
- Maintains security by still escaping dangerous JSDoc characters
- All tests pass (128/128) confirming no regressions

Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Copy link

changeset-bot bot commented Aug 20, 2025

🦋 Changeset detected

Latest commit: 37bf80a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
swagger-typescript-api Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI and others added 2 commits August 20, 2025 20:24
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
@smorimoto
Copy link
Collaborator

bugbot run

cursor[bot]

This comment was marked as outdated.

…yEscaped check

Co-authored-by: FDiskas <468006+FDiskas@users.noreply.github.com>
@FDiskas
Copy link
Author

FDiskas commented Aug 25, 2025

Updated PR

@smorimoto
Copy link
Collaborator

bugbot run

@smorimoto smorimoto added the bug Something isn't working label Aug 28, 2025
!_.isUndefined(field.example) &&
`@example ${_.isObject(field.example) ? JSON.stringify(field.example) : field.example}`,
`@example ${_.isObject(field.example) ? JSON.stringify(field.example) : escapeJSDocContent(field.example)}`,
Copy link

Choose a reason for hiding this comment

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

Bug: JSDoc Comment Injection Vulnerability

When field.example is an object, its JSON.stringify output isn't escaped. This allows */ sequences within the stringified content to prematurely close JSDoc comments, potentially enabling comment injection.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

⚠️ Vulnerability (all versions): Unescaped characters from description
3 participants