
analysis.ExploitString Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of regex-static-analysis Show documentation
Show all versions of regex-static-analysis Show documentation
A tool to perform static analysis on regexes to determine whether they are vulnerable to ReDoS.
package analysis;
/**
* A class that keeps the prefix and pump part of an input string to a vulnerable regular expression
* @author N. H. Weideman
*
*/
public class ExploitString {
private final static int VERBATIM_CHAR_MIN = 33; /* ! */
private final static int VERBATIM_CHAR_MAX = 126; /* ~ */
private final int degree;
public int getDegree() {
return degree;
}
private final String separators[];
public String getSeparatorByDegreeVisual(int degree) {
return visualiseString(separators[degree]);
}
public final String[] getSeparators() {
String[] separators = new String[degree];
for (int i = 0; i < degree; i++) {
separators[i] = this.separators[i];
}
return separators;
}
public String getPrefixVisual() {
return visualiseString(separators[0]);
}
public String getPrefix() {
return separators[0];
}
public String getSeparatorByDegree(int degree) {
return separators[degree];
}
private final String pumps[];
public String getPumpByDegreeVisual(int degree) {
return visualiseString(pumps[degree]);
}
public final String[] getPumps() {
String[] pumps = new String[degree];
for (int i = 0; i < degree; i++) {
pumps[i] = this.pumps[i];
}
return pumps;
}
public String getPumpByDegree(int degree) {
return pumps[degree];
}
private final String suffix;
public String getSuffixVisual() {
return visualiseString(suffix);
}
public String getSuffix() {
return suffix;
}
public ExploitString(String prefix, String pump, String suffix) {
this.degree = 0;
separators = new String[1];
separators[0] = prefix;
pumps = new String[1];
pumps[0] = pump;
this.suffix = suffix;
}
public ExploitString(String[] separators, String[] pumps, String suffix) {
this.degree = pumps.length;
if (separators.length != pumps.length) {
throw new IllegalArgumentException("There must be the same number of separators as pumps");
}
this.pumps = new String[degree];
this.separators = new String[degree];
for (int i = 0; i < degree; i++) {
if (separators[i] == null) {
throw new IllegalArgumentException("Null separators not allowed.");
}
if (pumps[i] == null) {
throw new IllegalArgumentException("Null pumps not allowed.");
}
this.pumps[i] = pumps[i];
this.separators[i] = separators[i];
}
this.suffix = suffix;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (degree <= 0) {
/* EDA exploit string */
sb.append(visualiseString(separators[0]));
sb.append(visualiseString(pumps[0]));
sb.append("...");
sb.append(visualiseString(pumps[0]));
} else {
for (int i = 0; i < degree; i++) {
sb.append(visualiseString(separators[i]));
sb.append(visualiseString(pumps[i]));
sb.append("...");
sb.append(visualiseString(pumps[i]));
}
}
String visibleSuffix = visualiseString(suffix);
sb.append(visibleSuffix);
return sb.toString();
}
public static String visualiseString(String s) {
StringBuilder sb = new StringBuilder();
char sArr[] = s.toCharArray();
for (int i = 0; i < sArr.length; i++) {
int c = (int) sArr[i];
if (c >= VERBATIM_CHAR_MIN && c <= VERBATIM_CHAR_MAX) {
sb.append(sArr[i]);
} else {
if (c < 256) {
sb.append(String.format("\\x%02x", c));
} else {
sb.append(String.format("\\x{%02x}", c));
}
}
}
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!o.getClass().isAssignableFrom(this.getClass())) {
return false;
}
ExploitString es = (ExploitString) o;
boolean testDegree = degree == es.degree;
boolean testPumps = false;
boolean testSeparators = false;
if (pumps == null) {
testPumps = es.pumps == null;
} else {
if (!testDegree) {
return false;
}
for (int i = 0; i < degree; i++) {
if (!separators[i].equals(es.separators[i])) {
testSeparators = false;
break;
}
if (!pumps[i].equals(es.pumps[i])) {
testPumps = false;
break;
}
}
}
boolean testSuffix = false;
if (suffix == null) {
testSuffix = es.suffix == null;
} else {
testSuffix = suffix.equals(es.suffix);
}
boolean condition = testDegree && testPumps && testSeparators && testSuffix;
return condition;
}
@Override
public int hashCode() {
return toString().hashCode();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy