Skip to content

fix: prevent reflected/path XSS in index rendering#50

Merged
puria merged 4 commits into
mainfrom
xss
Dec 22, 2025
Merged

fix: prevent reflected/path XSS in index rendering#50
puria merged 4 commits into
mainfrom
xss

Conversation

@puria

@puria puria commented Dec 22, 2025

Copy link
Copy Markdown
Member

Stop reflecting untrusted request paths into the app HTML; default invalid/out-of-root paths to / and only set
initial path when it’s an existing directory. Also escape terminal prompt and inline image HTML to avoid DOM/attribute
injection. Add regression tests for the reported payload.

Thanks to Keyur Maheta for the responsible disclosure.

Stop reflecting untrusted request paths into the app HTML; default invalid/out-of-root paths to  /  and only set
initial path when it’s an existing directory. Also escape terminal prompt and inline image HTML to avoid DOM/attribute
injection. Add regression tests for the reported payload.

Thanks to Keyur Maheta for the responsible disclosure.

Copilot AI 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.

Pull request overview

This PR fixes a reflected XSS vulnerability where untrusted request paths could be injected into the HTML response. The fix ensures that only validated, existing directory paths are used as the initial path, and all user-controlled values are properly escaped before rendering in HTML or JavaScript contexts.

Key changes:

  • Paths that don't exist or are outside the root now default to / instead of being reflected
  • HTML escaping applied to initial paths, terminal prompts, and image display
  • Client-side path validation to ensure paths start with /

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
main.go Adds path validation to only pass existing directories to serveMainIndex; adds HTML escaping to processHTMLTemplate, image HTML generation, and no-JS directory listings; adds redirect response for directories with index.html
index.html Moves initial path from direct template substitution to data attribute; adds escapeHTML to terminal prompt rendering; adds client-side path validation; adds redirect handling
handlers_test.go Adds regression tests for XSS payload rejection and valid directory path handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go Outdated
size = fmt.Sprintf(" (%d bytes)", info.Size())
}
_, _ = fmt.Fprintf(w, "<a href=\"%s\">%s</a>%s<br>\n", filePath, file.Name(), size)
_, _ = fmt.Fprintf(w, "<a href=\"%s\">%s</a>%s<br>\n", urlEscapeVirtual(filePath), template.HTMLEscapeString(file.Name()), size)

Copilot AI Dec 22, 2025

Copy link

Choose a reason for hiding this comment

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

The urlEscapeVirtual function does not escape HTML-sensitive characters like quotes, angle brackets, or apostrophes. When used in href attributes without additional HTML escaping, this could allow attribute injection. For defense in depth, consider applying template.HTMLEscapeString to URL values used in HTML attributes, or extend urlQueryEscape to handle quotes and angle brackets. For example, a filename containing a double quote could break out of the href attribute.

Copilot uses AI. Check for mistakes.
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread main.go
if virtualPath != "/" {
parentPath := path.Dir(virtualPath)
_, _ = fmt.Fprintf(w, "<a href=\"%s?nojs=1\">[Parent Directory]</a><br>\n", parentPath)
_, _ = fmt.Fprintf(w, "<a href=\"%s?nojs=1\">[Parent Directory]</a><br>\n", urlEscapeVirtual(parentPath))

Copilot AI Dec 22, 2025

Copy link

Choose a reason for hiding this comment

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

The urlEscapeVirtual function does not escape HTML-sensitive characters like quotes, angle brackets, or apostrophes. When used in href attributes without additional HTML escaping, this could allow attribute injection. For defense in depth, consider applying template.HTMLEscapeString to URL values used in HTML attributes, or extend urlQueryEscape to handle quotes and angle brackets. For example, a filename containing a double quote could break out of the href attribute.

Copilot uses AI. Check for mistakes.
Comment thread main.go Outdated
for _, dir := range dirs {
dirPath := path.Join(virtualPath, dir.Name())
_, _ = fmt.Fprintf(w, "<a href=\"%s?nojs=1\">%s/</a><br>\n", dirPath, dir.Name())
_, _ = fmt.Fprintf(w, "<a href=\"%s?nojs=1\">%s/</a><br>\n", urlEscapeVirtual(dirPath), template.HTMLEscapeString(dir.Name()))

Copilot AI Dec 22, 2025

Copy link

Choose a reason for hiding this comment

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

The urlEscapeVirtual function does not escape HTML-sensitive characters like quotes, angle brackets, or apostrophes. When used in href attributes without additional HTML escaping, this could allow attribute injection. For defense in depth, consider applying template.HTMLEscapeString to URL values used in HTML attributes, or extend urlQueryEscape to handle quotes and angle brackets. For example, a filename containing a double quote could break out of the href attribute.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

puria and others added 2 commits December 22, 2025 11:35
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Dec 22, 2025

Copy link
Copy Markdown
Contributor

@puria I've opened a new pull request, #51, to work on those changes. Once the pull request is ready, I'll request review from you.

…tribute injection (#51)

* Initial plan

* Use stdlib url.PathEscape and html.EscapeString for defense in depth

Co-authored-by: puria <10379+puria@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: puria <10379+puria@users.noreply.github.com>
@puria puria merged commit fd61ac9 into main Dec 22, 2025
4 checks passed
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.

3 participants