title: Escaping for proper shell injection prevention
body: <p>I need to run some shell commands from a Lua interpreter embedded into another Mac/Windows application where shell commands are the only way to achieve certain things, like opening a help page in a browser. If I have a list of arguments (which might be the result of user input), how can I escape each argument to prevent trouble?</p>
  
  <p>Inspired by <a href="http://qntm.org/bash" rel="noreferrer">this article</a> an easy solution seems to be to escape all non-alphanumeric characters, on Unix-like systems with <code>\</code>, on Windows with <code>^</code>.  As far as I can tell, this prevents that any argument will cause</p>
  
  <ul>
  <li>execution of another command because of on intervening newline, <code>;</code> (Unix) or <code>&amp;</code> (Windows)</li>
  <li>command substitution on Unix with <code>$</code> or <code>`</code></li>
  <li>variable evaluation on Windows with <code>%</code></li>
  <li>redirection with <code>&lt;</code>, <code>|</code> and <code>&gt;</code></li>
  </ul>
  
  <p>In addition, any character that on the respective platform works as escape character will be escaped properly.</p>
  
  <p>This seems sound to me, but are there any pitfalls I might have missed?  I know that in bash, <code>\</code> followed by a newline will effectively remove the newline, which is not a problem here.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>My conclusion: There is no single mechanism that by swapping the escape character will work on both Windows and *nix.  It turns out it is not so straightforward to make sure that a Windows program actually sees the command line arguments we want it to see as splitting the command string into arguments on Windows is not handled by the shell but by the called program itself.</p>
  
  <p>Therefore two layers of escaping need to be taken into account:</p>
  
  <ol>
  <li>First, the Windows shell will process what we give it.  What it might do is variable substitution at <code>%</code>, splitting into multiple commands at <code>&amp;</code> or piping to another command at <code>|</code>.</li>
  <li>Then, it will hand on a single command string to the called program which the program will split, ideally but not necessarily following the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft%28v=vs.85%29.aspx" rel="noreferrer">rules described by Microsoft</a>.</li>
  </ol>
  
  <p>Assuming it follows these rules, one can work one's way backwards, first escaping to these rules, then escaping further for the shell.</p>