Skip to content

Commit

Permalink
Fixed improper handling of response cookies. Update core.js.
Browse files Browse the repository at this point in the history
  • Loading branch information
ddwightx committed Mar 4, 2024
1 parent ee89d60 commit d353ce6
Show file tree
Hide file tree
Showing 11 changed files with 408 additions and 64 deletions.
2 changes: 1 addition & 1 deletion extension/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {

group 'com.synfron.reshaper.burp'
archivesBaseName = 'reshaper-for-burp'
version '2.3.1'
version '2.3.2'

targetCompatibility = '17'
sourceCompatibility = '17'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static String getRequestValue(EventInfo eventInfo, HttpRequestMessage req
case HttpRequestHeader -> requestMessage.getHeaders().getHeader(identifier.getText(eventInfo), itemPlacement);
case HttpRequestBody -> requestMessage.getBody().getText();
case HttpRequestStatusLine -> requestMessage.getStatusLine().getValue();
case HttpRequestCookie -> requestMessage.getHeaders().getCookies().getCookie(identifier.getText(eventInfo), itemPlacement);
case HttpRequestCookie -> requestMessage.getHeaders().getCookie(identifier.getText(eventInfo), itemPlacement);
case HttpRequestUri -> requestMessage.getStatusLine().getUrl().getValue();
case HttpRequestMessage -> requestMessage.getText();
case HttpRequestMethod -> requestMessage.getStatusLine().getMethod();
Expand All @@ -59,7 +59,7 @@ public static String getResponseValue(EventInfo eventInfo, HttpResponseMessage r
case HttpResponseHeader -> responseMessage.getHeaders().getHeader(identifier.getText(eventInfo), itemPlacement);
case HttpResponseBody -> responseMessage.getBody().getText();
case HttpResponseStatusLine -> responseMessage.getStatusLine().getValue();
case HttpResponseCookie -> responseMessage.getHeaders().getCookies().getCookie(identifier.getText(eventInfo), itemPlacement);
case HttpResponseCookie -> responseMessage.getHeaders().getCookie(identifier.getText(eventInfo), itemPlacement);
case HttpResponseMessage -> responseMessage.getText();
case HttpResponseStatusCode -> responseMessage.getStatusLine().getCode();
case HttpResponseStatusMessage -> responseMessage.getStatusLine().getMessage();
Expand Down Expand Up @@ -108,7 +108,7 @@ public static void setRequestValue(EventInfo eventInfo, HttpRequestMessage reque
case HttpRequestHeader -> requestMessage.getHeaders().setHeader(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpRequestBody -> requestMessage.setBody(StringUtils.defaultString(replacementText));
case HttpRequestStatusLine -> requestMessage.setStatusLine(replacementText);
case HttpRequestCookie -> requestMessage.getHeaders().getCookies().setCookie(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpRequestCookie -> requestMessage.getHeaders().setCookie(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpRequestUri -> requestMessage.getStatusLine().setUrl(replacementText);
case HttpRequestMethod -> requestMessage.getStatusLine().setMethod(replacementText);
case HttpRequestUriPath -> requestMessage.getStatusLine().getUrl().setPath(StringUtils.defaultString(replacementText));
Expand All @@ -124,7 +124,7 @@ public static void setResponseValue(EventInfo eventInfo, HttpResponseMessage res
case HttpResponseHeader -> responseMessage.getHeaders().setHeader(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpResponseBody -> responseMessage.setBody(StringUtils.defaultString(replacementText));
case HttpResponseStatusLine -> responseMessage.setStatusLine(replacementText);
case HttpResponseCookie -> responseMessage.getHeaders().getCookies().setCookie(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpResponseCookie -> responseMessage.getHeaders().setCookie(identifier.getText(eventInfo), replacementText, itemPlacement);
case HttpResponseStatusCode -> responseMessage.getStatusLine().setCode(replacementText);
case HttpResponseStatusMessage -> responseMessage.getStatusLine().setMessage(StringUtils.defaultString(replacementText));
}
Expand All @@ -134,8 +134,8 @@ public static List<String> getIdentifier(EventInfo eventInfo, MessageValue messa
return switch (messageValue) {
case HttpRequestHeader -> eventInfo.getHttpRequestMessage().getHeaders().getHeaderNames();
case HttpResponseHeader -> ((HttpEventInfo)eventInfo).getHttpResponseMessage().getHeaders().getHeaderNames();
case HttpRequestCookie -> eventInfo.getHttpRequestMessage().getHeaders().getCookies().getCookiesNames();
case HttpResponseCookie -> ((HttpEventInfo)eventInfo).getHttpResponseMessage().getHeaders().getCookies().getCookiesNames();
case HttpRequestCookie -> eventInfo.getHttpRequestMessage().getHeaders().getCookiesNames();
case HttpResponseCookie -> ((HttpEventInfo)eventInfo).getHttpResponseMessage().getHeaders().getCookiesNames();
case HttpRequestUriQueryParameter -> eventInfo.getHttpRequestMessage().getStatusLine().getUrl().getQueryParams().getParamNames();
default -> Collections.emptyList();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
public abstract class HttpHeaders extends HttpEntity {
protected final List<String> headerLines;
protected ListMap<CaseInsensitiveString, IValue<String>> headers;
private HttpCookies cookies;
private final String cookieHeaderName;
private boolean changed;
protected final String cookieHeaderName;
protected boolean changed;

public HttpHeaders(List<String> headerLines, String cookieHeaderName) {
this.headerLines = headerLines;
Expand All @@ -41,46 +40,37 @@ public void setHeader(String name, String value, SetItemPlacement itemPlacement)
if (value == null) {
deleteHeader(name, IItemPlacement.toDelete(itemPlacement));
} else if (name.equalsIgnoreCase(cookieHeaderName)) {
cookies = new HttpCookies(value);
headers.set(new CaseInsensitiveString(name), new Mapped<>(() -> this.cookies.getValue()), itemPlacement);
headers.setOrAdd(new CaseInsensitiveString(name), createCookie(value), itemPlacement);
} else {
headers.set(new CaseInsensitiveString(name), new Value<>(value), itemPlacement);
headers.setOrAdd(new CaseInsensitiveString(name), new Value<>(value), itemPlacement);
}
changed = true;
}

public void deleteHeader(String name, DeleteItemPlacement itemPlacement) {
getHeaders().remove(new CaseInsensitiveString(name), itemPlacement);
if (name.equalsIgnoreCase(cookieHeaderName)) {
cookies = null;
}
changed = true;
}

public HttpCookies getCookies() {
getHeaders();
return cookies != null ? cookies : new HttpCookies("").withPropertyAddedListener(cookies -> {
if (this.cookies == null) {
this.cookies = cookies;
headers.add(new CaseInsensitiveString(cookieHeaderName), new Mapped<>(() -> this.cookies.getValue()));
}
});
}
public abstract String getCookie(String cookieName, GetItemPlacement itemPlacement);

public abstract void setCookie(String cookieName, String value, SetItemPlacement itemPlacement);

public abstract IValue<String> createCookie(String value);

public List<String> getHeaderNames() {
return getHeaders().keys().stream().map(CaseInsensitiveString::toString).sorted().collect(Collectors.toList());
}

private ListMap<CaseInsensitiveString, IValue<String>> getHeaders() {
protected ListMap<CaseInsensitiveString, IValue<String>> getHeaders() {
if (headers == null) {
headers = new ListMap<>();
for (String headerLine : headerLines) {
if (headerLine.length() > 0) {
String[] headerParts = headerLine.split(":", 2);
String headerValue = CollectionUtils.elementAtOrDefault(headerParts, 1, "").stripLeading();
if (headerParts[0].equalsIgnoreCase(cookieHeaderName)) {
cookies = new HttpCookies(headerParts[1].trim());
headers.add(new CaseInsensitiveString(headerParts[0]), new Mapped<>(() -> this.cookies.getValue()));
headers.add(new CaseInsensitiveString(headerParts[0]), createCookie(headerValue.trim()));
} else {
headers.add(new CaseInsensitiveString(headerParts[0]), new Value<>(headerValue.trim()));
}
Expand All @@ -92,7 +82,7 @@ private ListMap<CaseInsensitiveString, IValue<String>> getHeaders() {

@Override
public boolean isChanged() {
return changed || (cookies != null && cookies.isChanged());
return changed;
}

public List<String> getValue() {
Expand All @@ -110,4 +100,8 @@ public List<String> getValue() {
public String getText() {
return String.join("\r\n", getValue());
}

public abstract List<String> getCookiesNames();

public abstract boolean containsCookie(String cookieName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@
import java.util.function.Consumer;
import java.util.stream.Collectors;

public class HttpCookies extends HttpEntity {
public class HttpRequestCookies extends HttpEntity implements IValue<String> {
private ListMap<CaseInsensitiveString, String> cookies;
private final String headerValue;
@Getter
private boolean changed;
@Getter @Setter
private Consumer<HttpCookies> propertyAddedListener;

public HttpCookies(String headerValue) {
public HttpRequestCookies(String headerValue) {
this.headerValue = headerValue;
}

Expand All @@ -32,9 +30,8 @@ public int getCount() {

public void setCookie(String name, String value, SetItemPlacement itemPlacement) {
if (value != null) {
getCookies().set(new CaseInsensitiveString(name), value, itemPlacement);
getCookies().setOrAdd(new CaseInsensitiveString(name), value, itemPlacement);
changed = true;
propertyAdded();
} else {
deleteCookie(name, IItemPlacement.toDelete(itemPlacement));
}
Expand Down Expand Up @@ -90,14 +87,8 @@ public String getValue() {
return String.join("; ", cookieEntries);
}

private void propertyAdded() {
if (propertyAddedListener != null) {
propertyAddedListener.accept(this);
}
}

public HttpCookies withPropertyAddedListener(Consumer<HttpCookies> consumer) {
propertyAddedListener = consumer;
return this;
@Override
public String toString() {
return getValue();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,63 @@
package synfron.reshaper.burp.core.messages.entities.http;

import synfron.reshaper.burp.core.rules.GetItemPlacement;
import synfron.reshaper.burp.core.rules.SetItemPlacement;
import synfron.reshaper.burp.core.utils.CaseInsensitiveString;
import synfron.reshaper.burp.core.utils.IValue;

import java.util.List;

public class HttpRequestHeaders extends HttpHeaders {
public HttpRequestHeaders(List<String> headerLines) {
super(headerLines, "Cookie");
}

@Override
public String getCookie(String cookieName, GetItemPlacement itemPlacement) {
HttpRequestCookies cookies = (HttpRequestCookies)getHeaders().get(new CaseInsensitiveString(cookieHeaderName), GetItemPlacement.Last);
if (cookies != null) {
return cookies.getCookie(cookieName, itemPlacement);
}
return null;
}

@Override
public void setCookie(String cookieName, String value, SetItemPlacement itemPlacement) {
HttpRequestCookies cookies = (HttpRequestCookies)getHeaders().get(new CaseInsensitiveString(cookieHeaderName), GetItemPlacement.Last);
if (cookies != null) {
cookies.setCookie(cookieName, value, itemPlacement);
if (value == null) {
if (cookies.getCount() == 0) {
getHeaders().removeLast(new CaseInsensitiveString(cookieHeaderName));
}
}
} else if (value != null) {
getHeaders().add(new CaseInsensitiveString(cookieName), createCookie(cookieName, value));
}
changed = true;
}

@Override
public IValue<String> createCookie(String value) {
return new HttpRequestCookies(value);
}

@Override
public List<String> getCookiesNames() {
HttpRequestCookies cookies = (HttpRequestCookies)getHeaders().get(new CaseInsensitiveString(cookieHeaderName), GetItemPlacement.Last);
if (cookies != null) {
return cookies.getCookiesNames();
}
return List.of();
}

@Override
public boolean containsCookie(String cookieName) {
HttpRequestCookies cookies = (HttpRequestCookies)getHeaders().get(new CaseInsensitiveString(cookieHeaderName), GetItemPlacement.Last);
return cookies != null && cookies.contains(cookieName);
}

private IValue<String> createCookie(String name, String value) {
return new HttpRequestCookies(String.format("%s=%s", name, value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public String getQueryParameter(String name, GetItemPlacement itemPlacement) {
public void setQueryParameter(String name, String value, SetItemPlacement itemPlacement) {
if (value != null) {
prepare();
params.set(name, value, itemPlacement);
params.setOrAdd(name, value, itemPlacement);
changed = true;
} else {
deleteParameter(name, IItemPlacement.toDelete(itemPlacement));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package synfron.reshaper.burp.core.messages.entities.http;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import synfron.reshaper.burp.core.rules.DeleteItemPlacement;
import synfron.reshaper.burp.core.rules.GetItemPlacement;
import synfron.reshaper.burp.core.rules.IItemPlacement;
import synfron.reshaper.burp.core.rules.SetItemPlacement;
import synfron.reshaper.burp.core.utils.CaseInsensitiveString;
import synfron.reshaper.burp.core.utils.CollectionUtils;
import synfron.reshaper.burp.core.utils.IValue;
import synfron.reshaper.burp.core.utils.ListMap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

public class HttpResponseCookie extends HttpEntity implements IValue<String> {

private String name;
private String value;
private String config;
private final String headerValue;
@Getter
private boolean changed;

public HttpResponseCookie(String headerValue) {
this.headerValue = headerValue;
}

public HttpResponseCookie(String name, String value) {
headerValue = String.format("%s=%s", name, value);
}

private void initialize() {
if (name == null) {
int configSeparatorIndex = headerValue.indexOf(";");
String setter = headerValue.substring(0, configSeparatorIndex >= 0 ? configSeparatorIndex : headerValue.length());
String[] setterParts = setter.split("=", 2);
name = setterParts[0];
value = CollectionUtils.elementAtOrDefault(setterParts, 1, "");
config = configSeparatorIndex >= 0 ? headerValue.substring(configSeparatorIndex) : "";
}
}

public void setCookieValue(String value) {
initialize();
this.value = value;
changed = true;
}

public String getCookieValue() {
initialize();
return value;
}

public String getValue() {
if (!isChanged()) {
return headerValue;
}
return String.format("%s=%s%s", name, value, config);
}

public String getName() {
initialize();
return name;
}

@Override
public String toString() {
return getValue();
}
}
Loading

0 comments on commit d353ce6

Please sign in to comment.