oss-fuzz/projects/guava/UrlEscapersFuzzer.java

82 lines
2.9 KiB
Java
Raw Normal View History

2022-09-18 00:51:14 +00:00
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium;
import com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow;
import com.google.common.base.Charsets;
import com.google.common.escape.Escaper;
import com.google.common.net.PercentEscaper;
import com.google.common.net.UrlEscapers;
import java.lang.IllegalArgumentException;
import java.net.URLDecoder;
public class UrlEscapersFuzzer {
/*
* These constants are private members copy-pasted from
* com.google.common.net.UrlEscapers.
*/
static final String URL_FORM_PARAMETER_OTHER_SAFE_CHARS = "-_.*";
static final String URL_PATH_OTHER_SAFE_CHARS_LACKING_PLUS =
"-._~" // Unreserved characters.
+ "!$'()*,;&=" // The subdelim characters (excluding '+').
+ "@:"; // The gendelim characters permitted in paths.
private static boolean containsUnsafeCharacters(String string, String additionalSafeChars) {
String safe = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/*
* The percent character is always safe.
*/
safe += "%";
safe += additionalSafeChars;
for (int i = 0; i < string.length(); ++i) {
if (safe.indexOf(string.charAt(i)) < 0) {
return true;
}
}
return false;
}
public static void testUrlEscaper(Escaper escaper, String additionalSafeChars, String sample, boolean plusIsSpace) {
String encoded = escaper.escape(sample);
if (containsUnsafeCharacters(encoded, additionalSafeChars)) {
throw new FuzzerSecurityIssueMedium("unsafe character was not escaped");
}
String percentEncoded = encoded.replace("+", (plusIsSpace ? "%20" : "%2B"));
String decoded = URLDecoder.decode(percentEncoded, Charsets.UTF_8);
if (!decoded.equals(sample)) {
throw new FuzzerSecurityIssueLow("escaped sequence not being decoded as expected");
}
}
private static void testPercentEncoderConstructor(String safe, boolean plusIsSpace) {
try {
new PercentEscaper(safe, plusIsSpace);
} catch (IllegalArgumentException e) {
/* documented, ignore */
}
}
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
try {
boolean plusIsSpace = data.consumeBoolean();
String value = data.consumeRemainingAsString();
testPercentEncoderConstructor(value, plusIsSpace);
testUrlEscaper(new PercentEscaper("", plusIsSpace), (plusIsSpace ? "+" : ""), value, plusIsSpace);
testUrlEscaper(UrlEscapers.urlFormParameterEscaper(), URL_FORM_PARAMETER_OTHER_SAFE_CHARS + "+", value, true);
testUrlEscaper(UrlEscapers.urlFragmentEscaper(), URL_PATH_OTHER_SAFE_CHARS_LACKING_PLUS + "+/?", value, false);
testUrlEscaper(UrlEscapers.urlPathSegmentEscaper(), URL_PATH_OTHER_SAFE_CHARS_LACKING_PLUS + "+", value, false);
} catch (IllegalArgumentException e) {
/* ignore */
} catch (Exception e) {
throw new FuzzerSecurityIssueLow("Undocumented Exception");
}
}
}