Author: jfrederic.clere(a)jboss.com
Date: 2007-08-22 04:38:46 -0400 (Wed, 22 Aug 2007)
New Revision: 233
Added:
tags/JBOSSWEB_2_0_0_GA_CP01/
Modified:
tags/JBOSSWEB_2_0_0_GA_CP01/src/share/classes/org/apache/tomcat/util/http/Cookies.java
tags/JBOSSWEB_2_0_0_GA_CP01/src/share/classes/org/apache/tomcat/util/http/ServerCookie.java
Log:
Fix CVE-2007-3382 and CVE-2007-3385.
Copied: tags/JBOSSWEB_2_0_0_GA_CP01 (from rev 226, tags/JBOSSWEB_2_0_0_GA)
Modified:
tags/JBOSSWEB_2_0_0_GA_CP01/src/share/classes/org/apache/tomcat/util/http/Cookies.java
===================================================================
---
tags/JBOSSWEB_2_0_0_GA/src/share/classes/org/apache/tomcat/util/http/Cookies.java 2007-08-15
15:50:29 UTC (rev 226)
+++
tags/JBOSSWEB_2_0_0_GA_CP01/src/share/classes/org/apache/tomcat/util/http/Cookies.java 2007-08-22
08:38:46 UTC (rev 233)
@@ -249,9 +249,11 @@
int endValue=startValue;
cc=bytes[pos];
- if( cc== '\'' || cc=='"' ) {
- startValue++;
- endValue=indexOf( bytes, startValue, end, cc );
+ if( cc=='"' ) {
+ endValue=findDelim3( bytes, startValue+1, end, cc );
+ if (endValue == -1) {
+ endValue=findDelim2( bytes, startValue+1, end );
+ } else startValue++;
pos=endValue+1; // to skip to next cookie
} else {
endValue=findDelim2( bytes, startValue, end );
@@ -335,28 +337,26 @@
return off;
}
- public static int indexOf( byte bytes[], int off, int end, byte qq )
+ /*
+ * search for cc but skip \cc as required by rfc2616
+ * (according to rfc2616 cc should be ")
+ */
+ public static int findDelim3( byte bytes[], int off, int end, byte cc )
{
while( off < end ) {
byte b=bytes[off];
- if( b==qq )
+ if ( b== '\\' ) {
+ off++;
+ off++;
+ continue;
+ }
+ if( b==cc )
return off;
off++;
}
- return off;
+ return -1;
}
- public static int indexOf( byte bytes[], int off, int end, char qq )
- {
- while( off < end ) {
- byte b=bytes[off];
- if( b==qq )
- return off;
- off++;
- }
- return off;
- }
-
// XXX will be refactored soon!
public static boolean equals( String s, byte b[], int start, int end) {
int blen = end-start;
@@ -412,7 +412,7 @@
/**
*
* Strips quotes from the start and end of the cookie string
- * This conforms to RFC 2109
+ * This conforms to RFC 2965
*
* @param value a <code>String</code> specifying the cookie
* value (possibly quoted).
@@ -423,8 +423,7 @@
private static String stripQuote( String value )
{
// log("Strip quote from " + value );
- if (((value.startsWith("\"")) &&
(value.endsWith("\""))) ||
- ((value.startsWith("'") &&
(value.endsWith("'"))))) {
+ if (value.startsWith("\"") &&
value.endsWith("\"")) {
try {
return value.substring(1,value.length()-1);
} catch (Exception ex) {
Modified:
tags/JBOSSWEB_2_0_0_GA_CP01/src/share/classes/org/apache/tomcat/util/http/ServerCookie.java
===================================================================
---
tags/JBOSSWEB_2_0_0_GA/src/share/classes/org/apache/tomcat/util/http/ServerCookie.java 2007-08-15
15:50:29 UTC (rev 226)
+++
tags/JBOSSWEB_2_0_0_GA_CP01/src/share/classes/org/apache/tomcat/util/http/ServerCookie.java 2007-08-22
08:38:46 UTC (rev 233)
@@ -130,6 +130,7 @@
//
// private static final String tspecials = "()<>@,;:\\\"/[]?={}
\t";
private static final String tspecials = ",; ";
+ private static final String tspecials2 = ",; \"";
/*
* Tests a string and returns true if the string counts as a
@@ -154,6 +155,19 @@
return true;
}
+ public static boolean isToken2(String value) {
+ if( value==null) return true;
+ int len = value.length();
+
+ for (int i = 0; i < len; i++) {
+ char c = value.charAt(i);
+
+ if (c < 0x20 || c >= 0x7f || tspecials2.indexOf(c) != -1)
+ return false;
+ }
+ return true;
+ }
+
public static boolean checkName( String name ) {
if (!isToken(name)
|| name.equalsIgnoreCase("Comment") // rfc2019
@@ -213,7 +227,7 @@
// this part is the same for all cookies
buf.append( name );
buf.append("=");
- maybeQuote(version, buf, value);
+ maybeQuote2(version, buf, value);
// XXX Netscape cookie: "; "
// add version 1 specific information
@@ -283,6 +297,17 @@
buf.append('"');
}
}
+ public static void maybeQuote2 (int version, StringBuffer buf,
+ String value) {
+ // special case - a \n or \r shouldn't happen in any case
+ if (isToken2(value)) {
+ buf.append(value);
+ } else {
+ buf.append('"');
+ buf.append(escapeDoubleQuotes(value));
+ buf.append('"');
+ }
+ }
// log
static final int dbg=1;
@@ -306,12 +331,14 @@
}
StringBuffer b = new StringBuffer();
+ char p = s.charAt(0);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
- if (c == '"')
+ if (c == '"' && p != '\\')
b.append('\\').append('"');
else
b.append(c);
+ p = c;
}
return b.toString();