moappi Json2html json2html.js cross site scripting
Description
A vulnerability was found in moappi Json2html up to 1.1.x and classified as problematic. This issue affects some unknown processing of the file json2html.js. The manipulation leads to cross site scripting. The attack may be initiated remotely. Upgrading to version 1.2.0 is able to address this issue. The name of the patch is 2d3d24d971b19a8ed1fb823596300b9835d55801. It is recommended to upgrade the affected component. The associated identifier of this vulnerability is VDB-216959.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A stored cross-site scripting vulnerability existed in moappi json2html before 1.2.0, allowing remote attackers to inject arbitrary JavaScript via unsanitized text input.
Vulnerability
CVE-2018-25053 is a cross-site scripting (XSS) vulnerability found in the moappi json2html JavaScript library up to version 1.1.x. The issue resides in the file json2html.js, where the library's handling of user-supplied text values did not properly escape or sanitize input before rendering it into HTML. The root cause was the absence of a dedicated 'text' attribute that would HTML-encode output; previously, all content was treated as raw HTML, allowing injection of arbitrary script elements. [1] [2]
Exploitation
The attack can be initiated remotely without authentication. An attacker could craft a malicious JSON template that includes JavaScript payloads in the 'text' property or in any field that the library processed as HTML. Because the library was used to render JSON data into web pages, any application embedding untrusted user data within a json2html template would become vulnerable. The exploit requires no special network access beyond the ability to supply malicious JSON to a target application. [1]
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of a victim's browser session. This can lead to session hijacking, theft of cookies or authentication tokens, defacement of the rendered page, and redirection to malicious sites. The vulnerability is classified as problematic with a CVSS vector not yet provided, but typical XSS impacts apply. [1]
Mitigation
The vulnerability was fixed in version 1.2.0, which introduced a new 'text' attribute that properly HTML-encodes content before insertion. The commit 2d3d24d971b19a8ed1fb823596300b9835d55801 implements this change by adding a case for 'text' that calls json2html.toText() to encode values. All users are recommended to upgrade to version 1.2.0 or later to prevent exploitation. [2] [3]
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
node-json2htmlnpm | < 1.2.0 | 1.2.0 |
Affected products
1Patches
19 files changed · +134 −44
examples/default.html+0 −16 removed@@ -1,16 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> - <head> - <title> json2html examples </title> - - <!-- Add JSON2HTML --> - <script type="text/javascript" src="../json2html.js"></script> - - </head> - <body> - <!-- Run the tests --> - <script type="text/javascript" src="example.nested.js"></script> - <script type="text/javascript" src="example.shorthand.js"></script> - <script type="text/javascript" src="example.escape.js"></script> - </body> -</html>
json2html.js+88 −26 modified@@ -1,4 +1,4 @@ -//Copyright (c) 2016 Crystalline Technologies +//Copyright (c) 2018 Crystalline Technologies // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), // to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, @@ -135,14 +135,61 @@ var json2html = { switch(key) { - //LEGACY support for tag + //DEPRECATED (use <> instead) case 'tag': + + //HTML element to render case '<>': //Do nothing as we have already created the element break; + + //Encode as text + case 'text': + //Get the transform value associated with this key + var _transform = transform[key]; + + //Determine what kind of object this is + // array => NOT SUPPORTED + // other => text + if(json2html._isArray(_transform)) { + //NOT Supported + } else if(typeof _transform === 'function') { + + //Get the result from the function + var temp = _transform.call(obj, obj, index); + + //Don't allow arrays as return objects from functions + if(!json2html._isArray(temp)) { + + //Determine what type of object was returned + switch(typeof temp){ + + //Not supported for text + case 'function': + case 'undefined': + case 'object': + break; + + //Append as text + // string, number, boolean + default: + //Insure we encode as text first + children.html += json2html.toText(temp); + break; + } + } + } else { + + //Get the encoded text associated with this element + html = json2html.toText( json2html._getValue(obj,transform,key,index) ); + } + break; - //LEGACY support for children + //DEPRECATED (use HTML instead) case 'children': + + //Encode as HTML + // accepts Array of children, functions, string, number, boolean case 'html': //Get the transform value associated with this key @@ -160,31 +207,35 @@ var json2html = { //Get the result from the function var temp = _transform.call(obj, obj, index); - - //Determine what type of object was returned - switch(typeof temp){ - - //Only returned by json2html.transform or $.json2html calls - case 'object': - //make sure this object is a valid json2html response object - // we ignore all other objects (since we don't know how to represent them in html) - if(temp.html !== undefined && temp.events !== undefined) children = json2html._append(children,temp); - break; - - //Not supported - case 'function': - case 'undefined': - break; - - //Append to html - // string, number, boolean - default: - children.html += temp; - break; - } + + //Don't allow arrays as return objects from functions + if(!json2html._isArray(temp)) { + + //Determine what type of object was returned + switch(typeof temp){ + + //Only returned by json2html.transform or $.json2html calls + case 'object': + //make sure this object is a valid json2html response object + // we ignore all other objects (since we don't know how to represent them in html) + if(temp.html !== undefined && temp.events !== undefined) children = json2html._append(children,temp); + break; + + //Not supported + case 'function': + case 'undefined': + break; + + //Append to html + // string, number, boolean + default: + children.html += temp; + break; + } + } } else { - //Create the html attribute for this element + //Get the HTML associated with this element html = json2html._getValue(obj,transform,key,index); } break; @@ -319,6 +370,17 @@ var json2html = { return(out); }, + + //Encode the html to text + 'toText':function(html) { + return html + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/\"/g, '"') + .replace(/\'/g, ''') + .replace(/\//g, '/'); + }, //Tokenizer '_tokenizer':function( tokenizers, doBuild ){
package.json+1 −1 modified@@ -6,7 +6,7 @@ }, "name": "json2html", "description": "json2html - HTML Templating", - "version": "1.0.1", + "version": "1.1.0", "homepage": "http://json2html.com", "repository": { "url": "https://github.com/moappi/json2html.git"
README.md+1 −1 modified@@ -28,7 +28,7 @@ Transform (template) ```javascript var transform = {"<>": "li", "id":"${id}", "html":[ - {"<>": "span", "html": "${name} (${year})"} + {"<>": "span", "text": "${name} (${year})"} ]}; ``` Plus JSON Data
test/index.html+17 −0 added@@ -0,0 +1,17 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> json2html tests </title> + + <!-- Add JSON2HTML --> + <script type="text/javascript" src="../json2html.js"></script> + + </head> + <body> + <!-- Run the tests --> + <script type="text/javascript" src="test.nested.js"></script> + <script type="text/javascript" src="test.shorthand.js"></script> + <script type="text/javascript" src="test.escape.js"></script> + <script type="text/javascript" src="test.text.js"></script> + </body> +</html>
test/test.escape.js+0 −0 renamedtest/test.nested.js+0 −0 renamedtest/test.shorthand.js+0 −0 renamedtest/test.text.js+27 −0 added@@ -0,0 +1,27 @@ + +(function() { + + //Test the handling of quoted strings + var test_data = [ + {"text":"<script>alert(0);</script> no alert"}, + {"text":"<strong>non highlighted</strong>"}, + {"text":"& (ampersand) : ' (single quote) : \" (double quote) "} + ]; + + var transform = [ + {"<>":"div", "text":"${text}"}, + {"<>":"div","text":[ + {"<>":"span","text":"this shouldn't be rendered"} + ]}, + {"<>":"div", "text":function(){ + return(this.text); + }}, + {"<>":"div", "text":function(){ + return(["not rendered"]); + }} + ]; + + var html = json2html.transform(test_data, transform); + + document.write('<h1>Text Encoding Test</h1>'+ html); +})();
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/moappi/json2html/commit/2d3d24d971b19a8ed1fb823596300b9835d55801ghsapatchWEB
- github.com/moappi/json2html/releases/tag/1.2.0ghsapatchWEB
- github.com/advisories/GHSA-79mp-cxp4-9p6rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-25053ghsaADVISORY
- vuldb.comghsasignaturepermissions-requiredWEB
- vuldb.comghsavdb-entryWEB
News mentions
0No linked articles in our index yet.