@sun-asterisk/sunlint
Version:
☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards
134 lines (133 loc) • 4.18 kB
JSON
{
"rule": {
"id": "S023",
"name": "Prevent JSON Injection and JSON eval attacks",
"description": "Prevent JSON injection attacks and unsafe JSON handling. Detects unsafe JSON.parse(), eval() with JSON, JSON.stringify in HTML context, and JSON handling without proper validation.",
"category": "security",
"severity": "error",
"languages": ["typescript", "javascript"],
"frameworks": ["express", "nestjs", "node", "react", "vue", "angular"],
"version": "1.0.0",
"status": "stable",
"tags": ["security", "json", "injection", "xss", "owasp", "eval"],
"references": [
"https://owasp.org/www-community/vulnerabilities/JSON_Injection",
"https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html",
"https://portswigger.net/web-security/dom-based/json-injection",
"https://cwe.mitre.org/data/definitions/94.html"
]
},
"configuration": {
"checkJsonParse": true,
"checkEvalWithJson": true,
"checkJsonStringifyInHtml": true,
"userInputSources": [
"localStorage",
"sessionStorage",
"window.location",
"location.search",
"location.hash",
"URLSearchParams",
"req.body",
"req.query",
"req.params",
"request.body",
"request.query",
"document.cookie",
"window.name",
"postMessage",
"fetch",
"axios"
],
"validationPatterns": [
"try",
"catch",
"typeof",
"instanceof",
"validate",
"check",
"isValid",
"sanitize",
"escape",
"filter"
],
"htmlContextPatterns": [
"innerHTML",
"outerHTML",
"insertAdjacentHTML",
"document.write",
".html(",
"<script",
"</script>"
]
},
"examples": {
"violations": [
{
"description": "Unsafe JSON.parse with user input",
"code": "const data = JSON.parse(localStorage.getItem('userData'));"
},
{
"description": "Using eval() to parse JSON",
"code": "const obj = eval('(' + jsonString + ')');"
},
{
"description": "JSON.stringify in HTML context without escaping",
"code": "element.innerHTML = JSON.stringify(userInput);"
},
{
"description": "Parsing URL parameters without validation",
"code": "const params = JSON.parse(new URLSearchParams(window.location.search).get('data'));"
}
],
"fixes": [
{
"description": "Validate input before parsing JSON",
"code": "try {\n const data = JSON.parse(localStorage.getItem('userData'));\n if (typeof data === 'object' && data !== null) {\n // Use data\n }\n} catch (e) {\n // Handle error\n}"
},
{
"description": "Always use JSON.parse instead of eval",
"code": "const obj = JSON.parse(jsonString);"
},
{
"description": "Escape JSON output when used in HTML",
"code": "element.textContent = JSON.stringify(userInput);\n// or\nelement.innerHTML = escapeHtml(JSON.stringify(userInput));"
}
]
},
"testing": {
"testCases": [
{
"name": "unsafe_json_parse_localstorage",
"type": "violation",
"description": "JSON.parse with localStorage without validation"
},
{
"name": "eval_with_json",
"type": "violation",
"description": "Using eval() to parse JSON data"
},
{
"name": "json_stringify_html_context",
"type": "violation",
"description": "JSON.stringify output in innerHTML"
},
{
"name": "safe_json_parse_with_trycatch",
"type": "clean",
"description": "JSON.parse with proper try-catch validation"
}
]
},
"performance": {
"complexity": "O(n)",
"description": "Linear complexity based on number of JSON operations in the source code"
},
"owaspMapping": {
"category": "A03:2021 – Injection",
"subcategories": [
"A05:2021 – Security Misconfiguration"
],
"description": "Validates that JSON parsing and handling is done safely to prevent injection attacks and XSS vulnerabilities"
}
}