Skip to content

fix Reflected server-side cross-site scripting in roles() #9388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

odaysec
Copy link

@odaysec odaysec commented Apr 19, 2025

{
"type": "redirect",
"message": log_data["message"],
"reason": "multiple_roles",
"redirect_url": redirect_url.url,
}

fix the issue need to ensure that any user-provided input included in the response is properly sanitized or escaped. Since the response is in JSON format, we should escape the log_data["message"] value to prevent any malicious content from being executed. The tornado.escape.xhtml_escape function can be used for this purpose, as it is designed to escape strings for safe inclusion in HTML or JSON.

The fix involves:

  1. Escaping the log_data["message"] value before including it in the response.
  2. Ensuring that all other user-provided inputs in the response are similarly sanitized or escaped.

POC

Directly writing user input (an HTTP request parameter) to a webpage without properly sanitizing the input first, allows for a cross-site scripting vulnerability. The following is a minimal flask app which shows a safe and unsafe way to render the given name back to the page. The first view is unsafe as first_name is not escaped, leaving the page vulnerable to cross-site scripting attacks. The second view is safe as first_name is escaped, so it is not vulnerable to cross-site scripting attacks.

from flask import Flask, request, make_response, escape

app = Flask(__name__)

@app.route('/unsafe')
def unsafe():
    first_name = request.args.get('name', '')
    return make_response("Your name is " + first_name)

@app.route('/safe')
def safe():
    first_name = request.args.get('name', '')
    return make_response("Your name is " + escape(first_name))

Recommendation

To guard against cross-site scripting, consider escaping the input before writing user input to the page. The standard library provides escaping functions: html.escape() for Python 3.2 upwards or cgi.escape() older versions of Python. Most frameworks also provide their own escaping functions, and flask.escape().

References

XSS (Cross Site Scripting) Prevention Cheat Sheet
Cross-site scripting
html.escape()
CWE-79
CWE-116

@jaydhulia
Copy link
Collaborator

Hi @odaysec,
Thank you for your security research regarding a potential vulnerability in ConsoleMe. We believe that responsible security research and disclosure help us continually improve how we keep our members, partners, and employees secure. For efficiency and to set clear expectations for both Netflix and researchers, we ask all researchers to please report potential vulnerabilities via our HackerOne bug bounty program (https://hackerone.com/netflix).

With that said, I have reviewed your PR request and determined that, in this case, this is not a vulnerability for a couple of reasons:

  1. The log_data["message"] field is a static string (https://github.com/Netflix/consoleme/blob/master/consoleme/handlers/v2/roles.py#L114-L116) and is defined as You have more than one role matching your query. Please select one. There's no user input included for this string.
  2. The response headers for this API endpoint include the content type as application/json, which indicates to modern browsers that the return response should not be interpreted as HTML but as JSON and, therefore, wouldn't result in XSS.

Thank you again for your research, and we look forward to seeing future submissions via our HackerOne program.

@jaydhulia jaydhulia closed this Jun 24, 2025
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.

2 participants