It happens when untrusted input is written into a page without escaping for the place it lands in. The main defense is context-aware output encoding, with a Content Security Policy as a second layer.