XSS, JSON Injection, and Output Encoding

XSS via json_encode in HTML attributes: a real attack vector and the correct defence

Security compliance — XSS, JSON Injection, and Output Encoding
Key takeaways
  • OWASP Top 10 continues to rank injection (which includes XSS) in the top three web application vulnerabilities globally.
  • JSON in onclick attributes is an XSS vector when the JSON contains unescaped characters. The fix requires both JSON_HEX flags and htmlspecialchars — not one or the other.
  • Content Security Policy (CSP) with 'script-src \'self\'' eliminates inline event handler XSS entirely — it's the most effective defence-in-depth layer for XSS.
Risk signals
  • json_encode() output embedded directly in onclick, href, or data attributes without HTML encoding.
  • No Content Security Policy header on the application.
  • XSS testing limited to <script>alert() payloads — missing attribute-based injection patterns.
Action items
  • Implement a json_attr() helper that applies JSON_HEX_* flags and htmlspecialchars(ENT_QUOTES) and use it exclusively for JSON-in-HTML-attributes.
  • Add a Content Security Policy header: at minimum, 'script-src \'self\'; object-src \'none\''.
  • Include attribute-based XSS payloads in your security test suite: '" onmouseover="alert(1)" x='.

Cross-site scripting (XSS) via JSON injection in HTML attributes is consistently underestimated because it requires an unusual combination of conditions: JSON output inside an HTML attribute, combined with content that contains HTML-special characters. When all three coincide — as they do in legal case data that contains names like "O'Brien" — the vulnerability is real.

Key Analysis

OWASP Top 10 continues to rank injection (which includes XSS) in the top three web application vulnerabilities globally.
JSON in onclick attributes is an XSS vector when the JSON contains unescaped characters. The fix requires both JSON_HEX flags and htmlspecialchars — not one or the other.
Content Security Policy (CSP) with 'script-src \'self\'' eliminates inline event handler XSS entirely — it's the most effective defence-in-depth layer for XSS.

Risk Signals

json_encode() output embedded directly in onclick, href, or data attributes without HTML encoding.
No Content Security Policy header on the application.
XSS testing limited to <script>alert() payloads — missing attribute-based injection patterns.

Action Items

Implement a json_attr() helper that applies JSON_HEX_* flags and htmlspecialchars(ENT_QUOTES) and use it exclusively for JSON-in-HTML-attributes.
Add a Content Security Policy header: at minimum, 'script-src \'self\'; object-src \'none\''.
Include attribute-based XSS payloads in your security test suite: '" onmouseover="alert(1)" x='.

LinkedIn

Technical Deep Dive

Read the technical deep dive

See the implementation walkthrough on govindpreetsingh.com

Read on govindpreetsingh.com →

Request a consultation

This is a lightweight intake endpoint for now. It is structured so the practice management system can later take over scheduling, conflict checks and matter creation.

Submitting this form does not create an advocate-client relationship. Please avoid sending confidential details until engagement is confirmed.