mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-02-04 11:55:11 -05:00
fix(frontend): Prevent reflected XSS in OAuth callback route (#11963)
## Summary Fixes a reflected cross-site scripting (XSS) vulnerability in the OAuth callback route. **Security Issue:** https://github.com/Significant-Gravitas/AutoGPT/security/code-scanning/202 ### Vulnerability The OAuth callback route at `frontend/src/app/(platform)/auth/integrations/oauth_callback/route.ts` was writing user-controlled data directly into an HTML response without proper sanitization. This allowed potential attackers to inject malicious scripts via OAuth callback parameters. ### Fix Added a `safeJsonStringify()` function that escapes characters that could break out of the script context: - `<` → `\u003c` - `>` → `\u003e` - `&` → `\u0026` This prevents any user-provided values from being interpreted as HTML/script content when embedded in the response. ### References - [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) - [CWE-79: Improper Neutralization of Input During Web Page Generation](https://cwe.mitre.org/data/definitions/79.html) ## Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Verified the OAuth callback still functions correctly - [x] Confirmed special characters in OAuth responses are properly escaped
This commit is contained in:
@@ -1,6 +1,17 @@
|
||||
import { OAuthPopupResultMessage } from "./types";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
/**
|
||||
* Safely encode a value as JSON for embedding in a script tag.
|
||||
* Escapes characters that could break out of the script context to prevent XSS.
|
||||
*/
|
||||
function safeJsonStringify(value: unknown): string {
|
||||
return JSON.stringify(value)
|
||||
.replace(/</g, "\\u003c")
|
||||
.replace(/>/g, "\\u003e")
|
||||
.replace(/&/g, "\\u0026");
|
||||
}
|
||||
|
||||
// This route is intended to be used as the callback for integration OAuth flows,
|
||||
// controlled by the CredentialsInput component. The CredentialsInput opens the login
|
||||
// page in a pop-up window, which then redirects to this route to close the loop.
|
||||
@@ -23,12 +34,13 @@ export async function GET(request: Request) {
|
||||
console.debug("Sending message to opener:", message);
|
||||
|
||||
// Return a response with the message as JSON and a script to close the window
|
||||
// Use safeJsonStringify to prevent XSS by escaping <, >, and & characters
|
||||
return new NextResponse(
|
||||
`
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
window.opener.postMessage(${JSON.stringify(message)});
|
||||
window.opener.postMessage(${safeJsonStringify(message)});
|
||||
window.close();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user