Skip to content

Commit

Permalink
Merge pull request #120 from SasanLabs/UI_Handling
Browse files Browse the repository at this point in the history
Adding XSS image tag vulnerability
  • Loading branch information
preetkaran20 authored Apr 25, 2020
2 parents 8bcc269 + 512ac56 commit 37742be
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sasanlabs.internal.utility.annotations;

/**
* Usage of this is to distinguish what is the response type from the VulnerableRestEndpoint.
* Actually we want backend to provide entire information to frontend so that frontend
* is not tightly coupled with backend. This is done with an intent that the backend can
* be consumer by any application without the use of frontend like say a CTF hosting
* platform need not to use the UserInterface provided by vulnerableApp.
*
* So this information will be returned with the response of /allEndPoints and /allEndPointsJson
* so that consumer can write the code as per the provided information by these endpoints.
*
* @author KSASAN [email protected]
*/
public enum ResponseType {
ENTIRE_HTML_PAGE,
JSON,
HTML_TAGS_ONLY
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@
* @return template name
*/
String htmlTemplate() default "sasan";

/**
* ResponseType helps the implementer to know what is the type of response returned from the
* rest/http api call. This is important for vulnerabilities which returns entire html or tags
* like XSS vulnerability. The default responseType is {@link ResponseType#JSON}.
* @return ResonseType for the vulnerability level.
*/
ResponseType responseType() default ResponseType.JSON;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.sasanlabs.internal.utility.GenericUtils;
import org.sasanlabs.internal.utility.LevelEnum;
import org.sasanlabs.internal.utility.annotations.ResponseType;
import org.sasanlabs.internal.utility.annotations.VulnerabilityLevel;
import org.sasanlabs.internal.utility.annotations.VulnerableServiceRestEndPoint;
import org.sasanlabs.service.bean.ResponseBean;
Expand All @@ -31,59 +32,58 @@ public void setParameterBean(ParameterBean urlParamBean) {

// Just adding User defined input(Untrusted Data) into Src tag is not secure.
// Can be broken by various ways
@VulnerabilityLevel(value = LevelEnum.LEVEL_1, descriptionLabel = "XSS_DIRECT_INPUT_SRC_ATTRIBUTE_IMG_TAG")
public ResponseBean getVulnerablePayloadLevelUnsecure() {
@VulnerabilityLevel(value = LevelEnum.LEVEL_1, descriptionLabel = "XSS_DIRECT_INPUT_SRC_ATTRIBUTE_IMG_TAG", htmlTemplate = "LEVEL_1/XSS", responseType = ResponseType.HTML_TAGS_ONLY)
public ResponseBean<String> getVulnerablePayloadLevel1() {
String vulnerablePayloadWithPlaceHolder = "<img src=%s/>";
StringBuilder payload = new StringBuilder();
for (Map.Entry<String, String> map : this.parameterBean.getQueryParamKeyValueMap().entrySet()) {
payload.append(String.format(vulnerablePayloadWithPlaceHolder, map.getValue()));
}
return new ResponseBean(GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()));
return new ResponseBean<String>(payload.toString());
}

// Adding Untrusted Data into Src tag between quotes is beneficial but not
// without escaping the input
@VulnerabilityLevel(value = LevelEnum.LEVEL_2, descriptionLabel = "XSS_QUOTES_ON_INPUT_SRC_ATTRIBUTE_IMG_TAG")
public ResponseBean getVulnerablePayloadLevelLow() {
@VulnerabilityLevel(value = LevelEnum.LEVEL_2, descriptionLabel = "XSS_QUOTES_ON_INPUT_SRC_ATTRIBUTE_IMG_TAG", htmlTemplate = "LEVEL_1/XSS", responseType = ResponseType.HTML_TAGS_ONLY)
public ResponseBean<String> getVulnerablePayloadLevel2() {
String vulnerablePayloadWithPlaceHolder = "<img src=\"%s\"/>";
StringBuilder payload = new StringBuilder();
for (Map.Entry<String, String> map : this.parameterBean.getQueryParamKeyValueMap().entrySet()) {
payload.append(String.format(vulnerablePayloadWithPlaceHolder, map.getValue()));
}
return new ResponseBean(GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()));
return new ResponseBean<String>(payload.toString());
}

// Good way for HTML escapes so hacker cannot close the tags but can use event
// handlers like onerror etc. eg:- ''onerror='alert(1);'
@VulnerabilityLevel(value = LevelEnum.LEVEL_3, descriptionLabel = "XSS_HTML_ESCAPE_ON_DIRECT_INPUT_SRC_ATTRIBUTE_IMG_TAG")
public ResponseBean getVulnerablePayloadLevelMedium() {
@VulnerabilityLevel(value = LevelEnum.LEVEL_3, descriptionLabel = "XSS_HTML_ESCAPE_ON_DIRECT_INPUT_SRC_ATTRIBUTE_IMG_TAG", htmlTemplate = "LEVEL_1/XSS", responseType = ResponseType.HTML_TAGS_ONLY)
public ResponseBean<String> getVulnerablePayloadLevelMedium() {
String vulnerablePayloadWithPlaceHolder = "<img src=%s/>";
StringBuilder payload = new StringBuilder();
for (Map.Entry<String, String> map : this.parameterBean.getQueryParamKeyValueMap().entrySet()) {
payload.append(
String.format(vulnerablePayloadWithPlaceHolder, StringEscapeUtils.escapeHtml4(map.getValue())));
}
return new ResponseBean(GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()));
return new ResponseBean<String>(payload.toString());
}


// Good way and can protect against attacks but it is better to have check on
// the input values provided if possible.
@VulnerabilityLevel(value = LevelEnum.LEVEL_4, descriptionLabel = "XSS_QUOTES_AND_WITH_HTML_ESCAPE_ON_INPUT_SRC_ATTRIBUTE_IMG_TAG")
public ResponseBean getVulnerablePayloadLevelHigh() {
@VulnerabilityLevel(value = LevelEnum.LEVEL_4, descriptionLabel = "XSS_QUOTES_AND_WITH_HTML_ESCAPE_ON_INPUT_SRC_ATTRIBUTE_IMG_TAG", htmlTemplate = "LEVEL_1/XSS", responseType = ResponseType.HTML_TAGS_ONLY)
public ResponseBean<String> getVulnerablePayloadLevelHigh() {
String vulnerablePayloadWithPlaceHolder = "<img src=\"%s\"/>";
StringBuilder payload = new StringBuilder();
for (Map.Entry<String, String> map : this.parameterBean.getQueryParamKeyValueMap().entrySet()) {
payload.append(
String.format(vulnerablePayloadWithPlaceHolder, StringEscapeUtils.escapeHtml4(map.getValue())));
}
return new ResponseBean(GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()));
return new ResponseBean<String>(payload.toString());
}

// Good way and can protect against attacks but it is better to have check on
// the input values provided if possible.
@VulnerabilityLevel(value = LevelEnum.SECURE, descriptionLabel = "XSS_QUOTES_AND_WITH_HTML_ESCAPE_PLUS_FILTERING_ON_INPUT_SRC_ATTRIBUTE_IMG_TAG")
public ResponseBean getVulnerablePayloadLevelSecure() {
@VulnerabilityLevel(value = LevelEnum.SECURE, descriptionLabel = "XSS_QUOTES_AND_WITH_HTML_ESCAPE_PLUS_FILTERING_ON_INPUT_SRC_ATTRIBUTE_IMG_TAG", htmlTemplate = "LEVEL_1/XSS", responseType = ResponseType.HTML_TAGS_ONLY)
public ResponseBean<String> getVulnerablePayloadLevelSecure() {
String vulnerablePayloadWithPlaceHolder = "<img src=\"%s\"/>";
Set<String> allowedValues = new HashSet<>();
allowedValues.add("image.png");
Expand All @@ -94,7 +94,7 @@ public ResponseBean getVulnerablePayloadLevelSecure() {
String.format(vulnerablePayloadWithPlaceHolder, StringEscapeUtils.escapeHtml4(map.getValue())));
}
}
return new ResponseBean(GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()));
return new ResponseBean<String>(payload.toString());
}

}
Binary file added src/main/resources/static/images/OWASP.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div id="XSS">
<div>
<div>
<input type="text" id="imageInputSrc"/>
<button id="loadImage">Load</button>
<div id="image"></div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function addingEventListenerToLoadImageButton() {
document.getElementById("loadImage").addEventListener('click',
function () {
let url = getUrlForVulnerabilityLevel();
doGetAjaxCall(appendResponseCallback, url + "?value=images/" + document.getElementById("imageInputSrc").value, false);
});
};
addingEventListenerToLoadImageButton();

function appendResponseCallback(data) {
let div = document.createElement("div");
document.getElementById("image").appendChild(div);
div.innerHTML = data;
}

0 comments on commit 37742be

Please sign in to comment.