<div>There is nothing that you have provided that indicates that this is a new class of vulnerability; this is a classic state management issue.&nbsp; The application is designed to have a password reset function, and in order for that function to behave properly application state must be enforced.
</div>
<div>&nbsp;</div>
<div>Essentially the issue here is that the application is not maintaining its state properly, and the result is that an attacker can force the application to engage in some unplanned&nbsp;functionality.&nbsp; Any web application must leverage some form of state management, and this is pretty easy for most developers to learn.&nbsp; What most developers have difficulty with is the idea that process flow should be enforced; if you have a 'Registration' module with 3 states, and a 'Password Reset' module with 4 states, then any state transition from the Registration module into the Password Reset module should result in the use being forced to start at Password Reset modules&nbsp;initial state.
</div>
<div>&nbsp;</div>
<div>Without a strong means of enforcing the application logic it is trivial to move an application from a known to an unknown state, and this is never a good thing in an application, let alone an application that must make decisions about security based on application state.
</div>
<div>&nbsp;</div>
<div>The reuse of the 'login' session variable in your example is still a case of poor software development, but if application state was properly maintained, then it wouldn't be an issue.<br>&nbsp;</div>
<div><span class="gmail_quote">On 1/13/06, <b class="gmail_sendername">Alla Bezroutchko</b> &lt;<a href="mailto:alla@scanit.be">alla@scanit.be</a>&gt; wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">Frank Knobbe wrote:<br>&gt; The proposed fix is -- besides being only specific to this example --<br>&gt; equally flawed. The underlying issue is that you trust user supplied
<br>&gt; data. When a user supplies a user name for login purposes, you should<br>&gt; only use that input to perform a search in your database. If a match has<br>&gt; been found, take a *trusted* value from your database, for example an
<br>&gt; index ID, and carry that in the session object to identify the user.<br><br>Suppose in my example resetpw3.php instead of doing<br><br>$_SESSION['login'] = $_POST['login'];<br><br>did<br><br>$_SESSION['login'] = $db-&gt;getOne(&quot;SELECT login FROM users WHERE login=?
<br>AND secret_answer=?&quot;, array($_POST['login'], $_POST['secret_answer']));<br><br>As you suggest it takes a trusted value from the database. It is still<br>does not prevent using register2.php to initialize $_SESSION['login']
<br>and then jump to resetpw4.php and have it use the value to change password.<br><br>&gt; In other words, don't accept any user input (even after proper input<br>&gt; validation) and carry it as trusted data in your session object. Don't
<br>&gt; base further decisions on this data. Since it is user supplied it can<br>&gt; not be trusted.<br><br>Are you saying that user supplied data should never ever be stored in<br>the session? Where do you suggest to keep the data that needs to be
<br>passed between different pages in the application?<br><br>Say you have a form that is filled in in several steps, each step being<br>a separate page. Where would you store the data that the user entered to<br>have it all available on the last page? I can only think of carrying it
<br>around in hidden form fields, and this is not always possible.<br><br>&gt; Your example is further flawed in that it allows the change of a<br>&gt; password without being properly authenticated. Just having a valid<br>
&gt; 'login' session object present doesn't indicate that the user is<br>&gt; authenticated.<br><br>I think it does, if 'login' session object is only ever set by the<br>authentication procedure after verifying user's credentials. I believe
<br>the usual approach to authentication in web applications is to check<br>user's credentials and then store something in the session that<br>indicates that the credentials were correct. Usually it is something<br>like a user ID or an object or JavaBean storing user information. Then
<br>every pafge that needs to check auth just checks if the session object<br>is present and valid.<br><br>How do applications that you encounter check if the user is authenticated?<br><br>&gt; I really, really hope this was just an example you made
<br>&gt; up, and not something you actually saw being used. If so, go back to<br>&gt; that web site with a clue-by-four and give it a few whacks.<br><br>I work for a company that does penetration testing, vulnerability<br>
assessments, and stuff like that. The contracts we usually sign do not<br>authorise us to apply blunt instruments to customers' web sites. :)<br><br>This particular example is made up. Giving real ones would violate<br>non-diclosure agrements. It is similar to the real ones in the way that
<br>it has the same problem - one storage location is used to keep both<br>trusted and untrusted data. I used the password reset example because<br>the security implications are clear and one don't need application<br>specific context to understand it. The bug does not have to do anything
<br>with authentication as such.<br><br>And, in case you are wondering, the real ones were just as bad. :)<br><br>Alla.<br>_______________________________________________<br>Full-Disclosure - We believe in it.<br>Charter: 
<a href="http://lists.grok.org.uk/full-disclosure-charter.html">http://lists.grok.org.uk/full-disclosure-charter.html</a><br>Hosted and sponsored by Secunia - <a href="http://secunia.com/">http://secunia.com/</a><br></blockquote>
</div><br><br clear="all"><br>-- <br>____<br>ygjb<br>Computer Science is no more about computers than astronomy is about telescopes. E. W. Dijkstra