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: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]