I am no expert on formal proofs, but I can at least point you in the right direction.
Searching for XSS vulnerabilities comes down to three elements:
- A finite set of untrusted entry point. XSS can only happen, if you process untrusted data. The first thing you have to do is identify all untrusted entry points. In a web application those are usually GET and POST parameters as well as headers. But there are potentially many more indirect / second order entry points like environment variables, untrusted database content, data fetched from untrusted local files or from remote, etc. If those sources are considered trusted or not, depends on your architecture and the attacker types you want to protect against.
- A finite set of locations where dynamically generated data is included in a server response (i.e. the website). To trigger a XSS vulnerability, an attacker must be able to create malicious output that is interpreted by at least one browser engine as script code. To identify all locations where this can happen, you have to analyze the output layer of the application and check where dynamically generated output is injected into the website.
- All paths between untrusted entry points (1) and potentially vulnerable output locations (2). Performing data flow analysis allows you to find all paths that connect (1) and (2). Each path has the potential to allow XSS, as it connects untrusted input to a potentially vulnerable data output location.
That's the model you are working with. The next step is tracing all identified paths and check for functions that validate or encode the data in a way that prevents XSS. This is tricky, because different types of output locations may require different types of filtering / encoding to protect against XSS. Only the correct method can protect against exploitation of a specific path.
Please note that I deliberately ignored additional protection mechanisms against XSS, which can be considered a second line of defense.
So what does this mean? Yes, you can find all XSS vulnerabilities if you are able to identify all untrusted entry points, all dynamically generated data output locations and all paths between them, including the verification that certain functions protect against specific types of XSS. So why isn't there a single source code scanner out there that will find all XSS vulnerabilities in a complex website?
Fulfilling any of those requirements is highly complicated in practice. Today's web applications consist of a huge amount of different frameworks, containing millions of lines of code. Entry points - especially second order entry points - are easily overlooked and often vast. Data flows are highly complicated, passing through a lot of frameworks and functions. Modern coding patterns (e.g. reflection) make data flow analysis even harder. Judging, if a validation function really protects against a specific type of XSS, can be complicated for certain types of input.
So while it seems to be feasible in theory, there is still no source code scanner out there, that can handle all those difficulties. Which means, no one had yet been able to implement this seemingly simple approach for a wide variety of technology stacks.