[Tex/LaTex] Escaping special LaTeX characters in user-defined input text

charactersSecurityverbatim

Background

Users can provide text, which is transformed using XSL into a LaTeX document. The XSL template that transforms the XML document (containing user-defined text) currently resembles:

<xsl:template match="user-text">
  <xsl:text>  \item </xsl:text>
  <xsl:apply-templates />
</xsl:template>

This is then transformed into:

\item This is the text the user provided.

Problem

This allows the user to submit maliciously crafted LaTeX:

\item This is the \{latex} the user provided.

Ideas

Some ideas:

  • \begin{verbatim} and \end{verbatim} cause the text to appear without formatting (i.e., a monospace font).
  • Write an XSLT function that escapes the special characters.

Question

What is the simplest way to ensure user-defined text does not get interpreted as LaTeX code?

Something like \begin{verbatim} would be perfect if it didn't change the font, and prevent text from wrapping.

Related

Best Answer

If you want to render LateX syntax harmless in user input it either requires balanced braces (so that you can pick up the material as an argument and pass it through \scantokens) or it requires es sequence of "stop" tokens that are known not to be part of the material, e.g., \end{verbatim} or + in in \verb+foo+.

Neither can be guaranteed if you have no control whatsoever about the user input, e.g., what would happen if you user writes: "This text contains \end{verbatim} and now I'm free to use \LaTeX{} code."? Then it will blow up or at least execute the second part.

So if safety is important then XSLT is the way to go in my opinion. If you can live with that danger than consider changing \verbatim@font which is command that sets up the font used in verbatim and \verb. Its default definition is

\def\verbatim@font{\normalfont\ttfamily}

So if you change this to do "nothing" then you would get the normal body font.

Update (sorry wrong time of the day)

Of course that doesn't solve the fact that "verbatim" does not wrap. To fix this what is really needed is to write your own version of a "verbatim" environment" that doesn't change spaces to active and doesn't add

  \obeylines \verbatim@font \@noligs
  \hyphenchar\font\m@ne
  \everypar \expandafter{\the\everypar \unpenalty}%

in the first place, as those are your offenders.