You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by bu...@apache.org on 2004/07/07 10:19:20 UTC
DO NOT REPLY [Bug 29943] New: -
TokenProcessor generates double tokens on fast processors
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=29943>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=29943
TokenProcessor generates double tokens on fast processors
Summary: TokenProcessor generates double tokens on fast
processors
Product: Struts
Version: Nightly Build
Platform: Other
OS/Version: Other
Status: NEW
Severity: Minor
Priority: Other
Component: Utilities
AssignedTo: dev@struts.apache.org
ReportedBy: e.vanoosten@chello.nl
On really fast processors the TokenProcessor may generate the same token twice.
This happens when System.currentTimeMillis() returns the same amount multiple
times. I have seen this happen on really fast systems.
Note that it is really unlikely that the bug will occur in reality since the
same user would have to request 2 forms simultaneously.
The following patch solves the bug anyway by using a random generator.
I have made more small changes that are not directly related to this bug:
- I did not understand why the existing implementation catches
IllegalStateException, so I removed it. Please keep the catch when I missed
something (or just to be sure).
- I did not understand why the existing implementation silently suppresses
NoSuchAlgorithmException, so I added some behaviour.
- The toHex method has been slightly improved.
/** A random generator to prevent double tokens on really fast systems. */
private Random randomGenerator;
/**
* Generate a new transaction token, to be used for enforcing a single
* request for a particular transaction.
*
* @param request The request we are processing
* @return the generated token
*/
private String generateToken(HttpServletRequest request) {
// The following data is used for a token:
// - id of the session
// - current time
// - some random bytes, on really fast machines the same
// time is often returned twice or more
// Note that a random is used instead of a sequence number
// to prevent the use of another synchronisation point.
HttpSession session = request.getSession();
byte id[] = session.getId().getBytes();
byte now[] = new Long(System.currentTimeMillis()).toString().getBytes();
byte rnd[] = new byte[] { (byte) randomGenerator.nextInt(), (byte)
randomGenerator.nextInt() };
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
md.update(rnd);
return toHex(md.digest());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Not a valid JRE: MD5 algorithm not supported");
}
}
/**
* Convert a byte array to a String of hexadecimal digits and return it.
* @param buffer The byte array to be converted
* @return a hex string representation of the byte array
*/
private static String toHex(byte buffer[]) {
StringBuffer sb = new StringBuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; i++) {
sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
}
return sb.toString();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org