Skip to content

bug(cli/mcp): a node name containing </script> breaks out of the inlined JSON and corrupts the offline visualizer page #1514

Description

@Shashankss1205

utils/visualize_graph.py:214 (graph JSON), :135 and :201 (title)

The graph payload is inlined into a <script> block via json.dumps. json.dumps escapes quotes and backslashes but not /, so any node name or file path containing the literal </script> closes the script element early and everything after it is parsed as markup.

Reproduction

$ .venv/bin/python -c "
from codegraphcontext.utils.visualize_graph import build_graph_data, open_in_browser
import tempfile, pathlib
nodes=[{'id':1,'label':'Function','name':'x</script><script>alert(1)</script>','file_path':'/a.py'}]
p = open_in_browser(build_graph_data(nodes, []), title='t',
                    output_path=str(pathlib.Path(tempfile.mkdtemp())/'g.html'))
html = pathlib.Path(p).read_text()
print('script-breakout present:', '</script><script>alert(1)' in html)
"
script-breakout present: True

The rendered document contains the closing tag verbatim inside what was meant to be a JSON string literal:

      "name": "x</script><script>alert(1)</script>",

title is interpolated unescaped at :135 and :201 as well.

Impact

Mostly a robustness problem: a node whose name contains </script> breaks the offline visualization page entirely (blank or malformed graph) with no indication why. Minified or bundled JS, HTML templates and test fixtures containing that string are all realistic sources — CGC already indexes .js and .html files, and this repo itself ships website/public/wasm/*.js.

It is also a genuine (if low-reach) injection: indexing an untrusted repository and opening the generated page executes markup from that repository's identifiers in the local browser.

Suggested fix

Escape </>/& in the serialized JSON before inlining — the standard treatment is replacing < with < (and / in </ with <\/) after json.dumps. HTML-escape title at both interpolation sites.


Environment
Commit c0e0bed (main)
Python 3.12.3, Linux

Reproduced with the snippet above.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: cli/mcpCLI commands, MCP tool contracts, docsbugSomething isn't workingseverity: lowCosmetic, dead code, or a narrow-trigger correctness issue

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions