<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Yep, I see the bug in 722 as bright as day. The inner loop was using the outer loops index. Wince.<br><br><div>--</div>
<div>Jim Manico</div><div>@Manicode</div><div>(808) 652-3805</div></div><div><br>On Jun 28, 2014, at 7:11 AM, "Kevin W. Wall" <<a href="mailto:kevin.w.wall@gmail.com">kevin.w.wall@gmail.com</a>> wrote:<br>
<br></div><blockquote type="cite"><div><div dir="ltr"><div class="gmail_default" style="font-family:courier new,monospace">Jim,<br><br></div><div class="gmail_default" style="font-family:courier new,monospace">For the sake of the CVE, all you need to tell them of what versions<br>

</div><div class="gmail_default" style="font-family:courier new,monospace">of ESAPI are vulnerable and what version it is fixed in, not the SVN rev#.<br></div><div class="gmail_default" style="font-family:courier new,monospace">

And we probably didn't revert to the original version because the<br>interface changed from union(char[], char[][) to union(char[]...).<br></div><div class="gmail_default" style="font-family:courier new,monospace"><br>

</div><div class="gmail_default" style="font-family:courier new,monospace">And if we do this, we will want a release that fixes it and if we<br>do that, we will have to find a new place to host the ESAPI jar / zip<br>file because Google Code no longer allows this and simply putting it<br>

in Maven Central is not sufficient because there are still a lot of<br></div><div class="gmail_default" style="font-family:courier new,monospace">'ant' users out there.  So any suggestions where we should host the<br>

download for ESAPI? Google suggests Google Drive but I'm open to other<br>options.<br><br></div><div class="gmail_default" style="font-family:courier new,monospace">-kevin<br></div></div><div class="gmail_extra"><br>
<br>
<div class="gmail_quote">On Sat, Jun 28, 2014 at 2:03 AM, Jim Manico <span dir="ltr"><<a href="mailto:jim.manico@owasp.org" target="_blank">jim.manico@owasp.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div dir="auto"><div>Jeff,</div><div><br></div><div>I see three versions of this code in the source over history. For the sake of the CVE report...</div>
<div><br></div><div>This was introduced at r387.</div><div><table style="border-collapse:collapse;padding:0px;margin:0px"><tbody style="padding:0px;margin:0px"><tr style="padding:0px;margin:0px">
<td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">        <br></span></td></tr><tr style="padding:0px;margin:0px">


<td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>/**<br>
</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * Union two character arrays.<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * <br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @param c1 the c1<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @param c2 the c2<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @return the char[]<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>     */</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>char</span><span>[]</span><span> </span><span>union</span><span>(</span><span>char</span><span>[]</span><span> c1</span><span>,</span><span> </span><span>char</span><span>[]</span><span> c2</span><span>)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>StringBuffer</span><span> sb </span><span>=</span><span> </span><span>new</span><span> </span><span>StringBuffer</span><span>();</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>for</span><span> </span><span>(</span><span>int</span><span> i </span><span>=</span><span> </span><span>0</span><span>;</span><span> i </span><span><</span><span> c1</span><span>.</span><span>length</span><span>;</span><span> i</span><span>++)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>            </span><span>if</span><span> </span><span>(!</span><span>contains</span><span>(</span><span>sb</span><span>,</span><span> c1</span><span>[</span><span>i</span><span>]))</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                sb</span><span>.</span><span>append</span><span>(</span><span>c1</span><span>[</span><span>i</span><span>]);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>for</span><span> </span><span>(</span><span>int</span><span> i </span><span>=</span><span> </span><span>0</span><span>;</span><span> i </span><span><</span><span> c2</span><span>.</span><span>length</span><span>;</span><span> i</span><span>++)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>            </span><span>if</span><span> </span><span>(!</span><span>contains</span><span>(</span><span>sb</span><span>,</span><span> c2</span><span>[</span><span>i</span><span>]))</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                sb</span><span>.</span><span>append</span><span>(</span><span>c2</span><span>[</span><span>i</span><span>]);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>char</span><span>[]</span><span> c3 </span><span>=</span><span> </span><span>new</span><span> </span><span>char</span><span>[</span><span>sb</span><span>.</span><span>length</span><span>()];</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        sb</span><span>.</span><span>getChars</span><span>(</span><span>0</span><span>,</span><span> sb</span><span>.</span><span>length</span><span>(),</span><span> c3</span><span>,</span><span> </span><span>0</span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>Arrays</span><span>.</span><span>sort</span><span>(</span><span>c3</span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>return</span><span> c3</span><span>;</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"> </span></td>


</tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><br></td></tr></tbody></table></div><div>This was introduced at r722 during a merge:</div>
<div><br></div><div><table style="border-collapse:collapse;padding:0px;margin:0px"><tbody style="padding:0px;margin:0px"><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>/**<br></span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)">     * Union multiple character arrays.<br></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)">     * <br></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @param list the char[]s to union<br></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @return the union of the char[]s<br></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>     */</span><span><br></span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top">


<span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>char</span><span>[]</span><span> </span><span>union</span><span>(</span><span>char</span><span>[]...</span><span> list</span><span>)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>StringBuilder</span><span> sb </span><span>=</span><span> </span><span>new</span><span> </span><span>StringBuilder</span><span>();</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">        <br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>for</span><span> </span><span>(</span><span>char</span><span>[]</span><span> characters </span><span>:</span><span> list</span><span>)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                </span><span>for</span><span> </span><span>(</span><span>int</span><span> i </span><span>=</span><span> </span><span>0</span><span>;</span><span> i </span><span><</span><span> list</span><span>.</span><span>length</span><span>;</span><span> i</span><span>++)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                    </span><span>if</span><span> </span><span>(!</span><span>contains</span><span>(</span><span>sb</span><span>,</span><span> characters</span><span>[</span><span>i</span><span>]))</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                        sb</span><span>.</span><span>append</span><span>(</span><span>list</span><span>[</span><span>i</span><span>]);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>char</span><span>[]</span><span> toReturn </span><span>=</span><span> </span><span>new</span><span> </span><span>char</span><span>[</span><span>sb</span><span>.</span><span>length</span><span>()];</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        sb</span><span>.</span><span>getChars</span><span>(</span><span>0</span><span>,</span><span> sb</span><span>.</span><span>length</span><span>(),</span><span> toReturn</span><span>,</span><span> </span><span>0</span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>Arrays</span><span>.</span><span>sort</span><span>(</span><span>toReturn</span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>return</span><span> toReturn</span><span>;</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"></tr></tbody></table><br></div><div><br></div><div>And this is your fix at r1943.</div><div><br></div><div><table style="border-collapse:collapse;padding:0px;margin:0px">


<tbody style="padding:0px;margin:0px"><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">        <br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>/**<br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * Union multiple character arrays.<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * <br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @param list the char[]s to union<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">     * @return the union of the char[]s<br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>     */</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>char</span><span>[]</span><span> </span><span>union</span><span>(</span><span>char</span><span>[]...</span><span> list</span><span>)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>StringBuilder</span><span> sb </span><span>=</span><span> </span><span>new</span><span> </span><span>StringBuilder</span><span>();</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)">        <br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                </span><span>for</span><span> </span><span>(</span><span>char</span><span>[]</span><span> characters </span><span>:</span><span> list</span><span>)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                        </span><span>for</span><span> </span><span>(</span><span> </span><span>char</span><span> c </span><span>:</span><span> characters </span><span>)</span><span> </span><span>{</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                                </span><span>if</span><span> </span><span>(</span><span> </span><span>!</span><span>contains</span><span>(</span><span> sb</span><span>,</span><span> c </span><span>)</span><span> </span><span>)</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                                        sb</span><span>.</span><span>append</span><span>(</span><span> c </span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                        </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>                </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><br>


</span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>char</span><span>[]</span><span> toReturn </span><span>=</span><span> </span><span>new</span><span> </span><span>char</span><span>[</span><span>sb</span><span>.</span><span>length</span><span>()];</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        sb</span><span>.</span><span>getChars</span><span>(</span><span>0</span><span>,</span><span> sb</span><span>.</span><span>length</span><span>(),</span><span> toReturn</span><span>,</span><span> </span><span>0</span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>Arrays</span><span>.</span><span>sort</span><span>(</span><span>toReturn</span><span>);</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>        </span><span>return</span><span> toReturn</span><span>;</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><span>    </span><span>}</span><span><br>


</span></span></td></tr><tr style="padding:0px;margin:0px"><td style="padding:0px 0px 0px 4px;margin:0px;white-space:pre-wrap;vertical-align:top"><span style="white-space:normal;background-color:rgba(255,255,255,0)"><br>


</span></td></tr><tr style="padding:0px;margin:0px"></tr></tbody></table>I'm wondering why we did not revert back to the original code. Can a few of you eyeball this sequence?</div><div><br></div>
<div>Aloha,<div class=""><br><div>--</div><div>Jim Manico</div><div>@Manicode</div><div>(808) 652-3805</div></div></div><div><br><div class="">On Jun 28, 2014, at 3:17 AM, Jeff Williams <<a href="mailto:jeff.williams@aspectsecurity.com" target="_blank">jeff.williams@aspectsecurity.com</a>> wrote:<br>


<br></div></div><div><div class="h5"><blockquote type="cite"><div><span>Everyone,</span><br><span></span><br><span>I found the problem.  The real problem.  There was a change introduced in StringUtilities r722 that broke the union() method.  This method was used to generate the EncoderConstants.CHAR_ALPHANUMERICS set used in the test case.</span><br>


<span></span><br><span>I've checked in a fix and test cases to verify that it works.  I also added a very simple test case for getRandomString() that verifies that the method generates roughly the same number of each character across a bunch of generated strings.  Not perfect but at least sensitive enough to recognize if something is way off.</span><br>


<span></span><br><span>The good news is that order has been restored to the universe, and our Burp test suite results are back to 'excellent'.  If you'd like to verify this yourself (and I strongly encourage you to do so) I included a small utility to generate random tokens as a main() method in RandomizerTest.</span><br>


<span></span><br><span>    /**</span><br><span>     * Run this class to generate a file named "tokens.txt" with 20,000 random 20 character ALPHANUMERIC tokens.</span><br><span>     * Use Burp Pro sequencer to load this file and run a series of randomness tests.</span><br>


<span>     * </span><br><span>     * NOTE: be careful not to include any CRLF characters (10 or 13 ASCII) because they'll create new tokens</span><br><span>     * Check to be sure your analysis tool loads exactly 20,000 tokens of 20 characters each.</span><br>


<span>     */</span><br><span>    public static void main(String[] args) throws IOException {</span><br><span>        FileWriter fw = new FileWriter("tokens.txt");</span><br><span>        for (int i = 0; i < 20000; i++) {</span><br>


<span>            String token = ESAPI.randomizer().getRandomString(20, EncoderConstants.CHAR_ALPHANUMERICS);</span><br><span>            fw.write(token + "\n");</span><br><span>        }</span><br><span>        fw.close();</span><br>


<span>    }</span><br><span></span><br><span>Thanks to everyone who put some thought into the issue.</span><br><span></span><br><span>--Jeff</span><br><span></span><br><span></span><br><span>-----Original Message-----</span><br>


<span>From: Jim Manico [<a href="mailto:jim.manico@owasp.org" target="_blank">mailto:jim.manico@owasp.org</a>] </span><br><span>Sent: Thursday, June 26, 2014 1:30 AM</span><br><span>To: Kevin W. Wall</span><br><span>Cc: Jeff Williams; Bruno Girin; <a href="mailto:esapi-dev@lists.owasp.org" target="_blank">esapi-dev@lists.owasp.org</a>; <a href="mailto:esapi-user@lists.owasp.org" target="_blank">esapi-user@lists.owasp.org</a></span><br>


<span>Subject: Re: [Esapi-user] ESAPI Random Number Generation Broken</span><br><span></span><br><span>I'll track these issues on google code as soon as I get to a real computer. Everything you say makes perfect sense to me and I appreciate your time.</span><br>


<span></span><br><span>I'm still going to chase down DJB's SecureRandom hack for our analysis. (Dr) Steven Murdoch is here in Cambridge and made that suggestion.</span><br><span></span><br><span>Cheers, Kevin.</span><br>


<span>--</span><br><span>Jim Manico</span><br><span>@Manicode</span><br><span>(808) 652-3805</span><br><span></span><br><blockquote type="cite"><span>On Jun 26, 2014, at 5:39 AM, "Kevin W. Wall" <<a href="mailto:kevin.w.wall@gmail.com" target="_blank">kevin.w.wall@gmail.com</a>> wrote:</span><br>


</blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>On Wed, Jun 25, 2014 at 9:57 AM, Jim Manico <<a href="mailto:jim.manico@owasp.org" target="_blank">jim.manico@owasp.org</a>> wrote:</span><br>


</blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>PS: Java 8 improves upon this and provides a new API:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.h" target="_blank">http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.h</a></span><br>


</blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>tml#getInstanceStrong-- which is what we should be using for " </span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">


<span>high-value/long-lived secrets like RSA public/private keys". But even </span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>then, using the same instance without reseeding with lead to a PRNG, </span><br>


</blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>not a CRNG sequence.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>That's all well and good, but even with JDK 7 and earlier, </span><br>


</blockquote><blockquote type="cite"><span>SecureRandom</span><br></blockquote><blockquote type="cite"><span>*is* a CSRNG. (Note that a CSRNG *is* a PRNG.)  The problems with </span><br></blockquote><blockquote type="cite">


<span>SecureRandom very early own is that they just punted on the initial </span><br></blockquote><blockquote type="cite"><span>pseudo-random seed. Before JDK 1.4 (I think that's where it was </span><br></blockquote>

<blockquote type="cite">
<span>changed), the first time they set the seed, they did some black magic </span><br></blockquote><blockquote type="cite"><span>like mixing together a few bits from the current time in milliseconds, </span><br></blockquote>


<blockquote type="cite"><span>the current amount of total and available memory in the Java heap, and </span><br></blockquote><blockquote type="cite"><span>added in how many times a thread could yield in 3 seconds.  Near boot </span><br>


</blockquote><blockquote type="cite"><span>time, all those things were very predictable. In 1.4 (maybe 1.3), it </span><br></blockquote><blockquote type="cite"><span>was changed to initialize the seed /dev/urandom if it was available </span><br>


</blockquote><blockquote type="cite"><span>and if not, I think it reverted to some other song and dance.  There </span><br></blockquote><blockquote type="cite"><span>is problems however with /dev/urandom shortly after boot time (and </span><br>


</blockquote><blockquote type="cite"><span>ESPECIALLY shortly after the *initial* system boot). Using /dev/random </span><br></blockquote><blockquote type="cite"><span>would be better, but unfortunately that will block. (Aside: At my </span><br>


</blockquote><blockquote type="cite"><span>previous job, we wrote an EntropyPool to seed things like SecureRandom </span><br></blockquote><blockquote type="cite"><span>that would read from /dev/random by default or alternately </span><br>


</blockquote><blockquote type="cite"><span>/dev/urandom. There was a warning in the Javadoc if would block and to </span><br></blockquote><blockquote type="cite"><span>use the weaker entropy setting if that was a concern. It was never a </span><br>


</blockquote><blockquote type="cite"><span>problem until one time when an application had a new release and they </span><br></blockquote><blockquote type="cite"><span>started requesting [for some unknown reason] about 10k worth of data </span><br>


</blockquote><blockquote type="cite"><span>from this EntropyPool all at once. And it was in an /etc/init.d script </span><br></blockquote><blockquote type="cite"><span>that started their application in WebLogic Server. Result was they had </span><br>


</blockquote><blockquote type="cite"><span>a 20+ minute startup delay until 10k bytes could be collected from </span><br></blockquote><blockquote type="cite"><span>/dev/random. They called me in the middle of the night to 'yell' at </span><br>


</blockquote><blockquote type="cite"><span>me. I nicely told them to RTFM. Sigh.)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Anyway, my guess is that getInstanceStrong() method will allow you to </span><br>


</blockquote><blockquote type="cite"><span>specify things like "use /dev/random".  However, I agree with Thomas </span><br></blockquote><blockquote type="cite"><span>Ptacek's comment that if it really matters use an Operating </span><br>


</blockquote><blockquote type="cite"><span>System-level CSRNG and not a userspace CSRNG. There are of course </span><br></blockquote><blockquote type="cite"><span>reasons why you might not want to. Always using /dev/urandom is a </span><br>


</blockquote><blockquote type="cite"><span>reasonable compromise, but there are still edge cases where you can </span><br></blockquote><blockquote type="cite"><span>get burned by using /dev/urandom rather than /dev/random. But unless </span><br>


</blockquote><blockquote type="cite"><span>you are protecting nuclear launch codes (and seriously, you BETTER not </span><br></blockquote><blockquote type="cite"><span>be doing that with Java since you can't guarentee that you clear </span><br>


</blockquote><blockquote type="cite"><span>memory), /dev/urandom will probably suffice.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Also, one thing that I picked up on the Cigital blog post</span><br>


</blockquote><blockquote type="cite"><span>(<a href="http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-j" target="_blank">http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-j</a></span><br>

</blockquote>
<blockquote type="cite"><span>avas-securerandom/) was that an attacker could potentially hide a call </span><br></blockquote><blockquote type="cite"><span>like this</span><br></blockquote><blockquote type="cite"><span></span><br>


</blockquote><blockquote type="cite"><span>   System.setProperty("securerandom.source", "/dev/zero");</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite">


<span>in some 3rd party library that you are using and then your are toast.</span><br></blockquote><blockquote type="cite"><span>Of course, the same is true if you don't specify that you want the Sun </span><br></blockquote>


<blockquote type="cite"><span>provider as in:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>   SecureRandom csrng = SecureRandom.getInstance("SHA1PRNG", "SUN");</span><br>


</blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>as someone could dynamically insert their own tainted provider for </span><br></blockquote><blockquote type="cite"><span>SecureRandom into a 3rd party library you are using and again you are </span><br>


</blockquote><blockquote type="cite"><span>screwed. (Unless of course you are using a Java SecurityManager and an </span><br></blockquote><blockquote type="cite"><span>appropriately locked-down security policy which I am sure that you </span><br>


</blockquote><blockquote type="cite"><span>*all* are doing, right. Cough, cough.)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Anyhow, we need to do something about those two things in ESAPI...</span><br>


</blockquote><blockquote type="cite"><span>especially the first since it would be really subtle. Anyone care to </span><br></blockquote><blockquote type="cite"><span>write up a Google issue to that effect to remind me?</span><br>


</blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Cheers,</span><br></blockquote><blockquote type="cite"><span>-kevin</span><br></blockquote><blockquote type="cite"><span>--</span><br>


</blockquote><blockquote type="cite"><span>Blog: <a href="http://off-the-wall-security.blogspot.com/" target="_blank">http://off-the-wall-security.blogspot.com/</a></span><br></blockquote><blockquote type="cite"><span>NSA: All your crypto bit are belong to us.</span><br>


</blockquote></div></blockquote></div></div></div>
</blockquote></div><br><br clear="all"><br>-- <br>Blog: <a href="http://off-the-wall-security.blogspot.com/" target="_blank">http://off-the-wall-security.blogspot.com/</a><br>NSA: All your crypto bit are belong to us.
</div>
</div></blockquote></body></html>