<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/taint.detail.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'uk',
  ),
  'this' => 
  array (
    0 => 'taint.detail.basic.php',
    1 => 'How the taint mark is propagated',
    2 => 'How the taint mark is propagated',
  ),
  'up' => 
  array (
    0 => 'taint.detail.php',
    1 => 'Propagation and Checked Sinks',
  ),
  'prev' => 
  array (
    0 => 'taint.detail.php',
    1 => 'Propagation and Checked Sinks',
  ),
  'next' => 
  array (
    0 => 'taint.detail.sinks.php',
    1 => 'Where taint raises warnings',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    'path' => 'reference/taint/detail.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="taint.detail.basic" class="section">
  <h2 class="title">How the taint mark is propagated</h2>
  <p class="simpara">
   The taint mark is a single bit stored on the string itself, not on the
   variable holding it. Assigning, passing or otherwise sharing a tainted
   string keeps the mark. String concatenation and interpolation propagate
   it as well:
  </p>
  <p class="para">
   <table class="doctable table">
    <caption><strong>Operators which propagate the taint mark</strong></caption>
    
     <tbody class="tbody">
      <tr>
       <td><code class="literal">=</code> (assignment, including <code class="literal">list()</code>/<code class="literal">array destructuring</code>)</td>
      </tr>

      <tr>
       <td><code class="literal">.</code> (concatenation)</td>
      </tr>

      <tr>
       <td><code class="literal">.=</code> (concatenating assignment)</td>
      </tr>

      <tr>
       <td><code class="literal">&quot;{$var}&quot;</code> (string interpolation, including the <code class="literal">ROPE</code> fast path)</td>
      </tr>

     </tbody>
    
   </table>

  </p>
  <p class="simpara">
   In addition, taint understands a fixed set of string functions: when any
   of the relevant string arguments is tainted, the returned string is
   marked tainted too. Both the regular call and, on PHP 8.4+, the
   frameless fast-path call are covered.
  </p>
  <p class="para">
   <table class="doctable table">
    <caption><strong>Functions which propagate the taint mark</strong></caption>
    
     <tbody class="tbody">
      <tr>
       <td><span class="function"><a href="function.trim.php" class="function">trim()</a></span>, <span class="function"><a href="function.rtrim.php" class="function">rtrim()</a></span>, <span class="function"><a href="function.ltrim.php" class="function">ltrim()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.substr.php" class="function">substr()</a></span>, <span class="function"><a href="function.strstr.php" class="function">strstr()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.str-replace.php" class="function">str_replace()</a></span>, <span class="function"><a href="function.str-ireplace.php" class="function">str_ireplace()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.str-pad.php" class="function">str_pad()</a></span>, <span class="function"><a href="function.strtolower.php" class="function">strtolower()</a></span>, <span class="function"><a href="function.strtoupper.php" class="function">strtoupper()</a></span>, <span class="function"><a href="function.strval.php" class="function">strval()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.explode.php" class="function">explode()</a></span> (every element of the resulting array)</td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.implode.php" class="function">implode()</a></span>/<span class="function"><a href="function.join.php" class="function">join()</a></span> (a tainted separator taints the result as well)</td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.sprintf.php" class="function">sprintf()</a></span>, <span class="function"><a href="function.vsprintf.php" class="function">vsprintf()</a></span> (only the <code class="literal">%s</code> specifier carries the mark; <code class="literal">sprintf(&quot;%d&quot;, $t)</code> returns a clean string)</td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.dirname.php" class="function">dirname()</a></span>, <span class="function"><a href="function.basename.php" class="function">basename()</a></span>, <span class="function"><a href="function.pathinfo.php" class="function">pathinfo()</a></span></td>
      </tr>

     </tbody>
    
   </table>

  </p>
  <p class="simpara">
   Any function taint does not explicitly understand returns a fresh,
   unmarked string — including escaping helpers such as
   <span class="function"><a href="function.htmlspecialchars.php" class="function">htmlspecialchars()</a></span>, <span class="function"><a href="function.htmlentities.php" class="function">htmlentities()</a></span> or
   <span class="function"><a href="mysqli.real-escape-string.php" class="function">mysqli_real_escape_string()</a></span>. This is deliberate: taint
   over-reports rather than trying to decide whether a value is
   <q class="quote">safe</q> for a particular output context. Use
   <span class="function"><a href="function.untaint.php" class="function">untaint()</a></span> to clear the mark on values you have validated
   yourself.
  </p>
 </div><?php manual_footer($setup); ?>