Skip to content

Commit

Permalink
Merge pull request akto-api-security#345 from akto-api-security/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ankush-jain-akto committed Jun 24, 2023
2 parents aaf0a24 + 95d35d6 commit afbe75e
Show file tree
Hide file tree
Showing 26 changed files with 608 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public String generateBurpRequest() {
}

Map<String, String> result = generateBurpRequestFromSampleData(sampleData);
burpRequest = result.get("request");
burpRequest = result.get("request_path");
return SUCCESS.toUpperCase();
}

Expand All @@ -100,9 +100,8 @@ private Map<String, String> generateBurpRequestFromSampleData(String sampleData)
originalHttpRequest.buildFromApiSampleMessage(sampleData);
}

StringBuilder builder = new StringBuilder("");

String url = originalHttpRequest.getFullUrlWithParams();
String path = originalHttpRequest.getPath();

if (!url.startsWith("http")) {
String host = originalHttpRequest.findHostFromHeader();
Expand All @@ -114,6 +113,21 @@ private Map<String, String> generateBurpRequestFromSampleData(String sampleData)
}
}

StringBuilder builderWithUrl = buildRequest(originalHttpRequest, url);
StringBuilder builderWithPath = buildRequest(originalHttpRequest, path);

Map<String, String> result = new HashMap<>();
result.put("request", builderWithUrl.toString());
result.put("url", url);
result.put("type", originalHttpRequest.getType());
result.put("request_path", builderWithPath.toString());

return result;
}

private StringBuilder buildRequest(OriginalHttpRequest originalHttpRequest, String url) {
StringBuilder builder = new StringBuilder("");

// METHOD and PATH
builder.append(originalHttpRequest.getMethod()).append(" ")
.append(url).append(" ")
Expand All @@ -127,13 +141,7 @@ private Map<String, String> generateBurpRequestFromSampleData(String sampleData)

// BODY
builder.append(originalHttpRequest.getBody());

Map<String, String> result = new HashMap<>();
result.put("request", builder.toString());
result.put("url", url);
result.put("type", originalHttpRequest.getType());

return result;
return builder;
}

private String generateBurpResponseFromSampleData(String sampleData, String httpType) {
Expand Down
45 changes: 44 additions & 1 deletion apps/dashboard/src/main/java/com/akto/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static Map<String, String> convertApiInAktoFormat(JsonNode apiInfo, Map<S
result.put("requestHeaders", requestHeadersString);

JsonNode bodyNode = request.get("body");
String requestPayload = bodyNode != null ? bodyNode.asText() : "";
String requestPayload = extractRequestPayload(bodyNode);
requestPayload = replaceVariables(requestPayload, variables);

JsonNode responseNode = apiInfo.get("response");
Expand Down Expand Up @@ -170,6 +170,49 @@ public static Map<String, String> convertApiInAktoFormat(JsonNode apiInfo, Map<S
}
}

public static String extractRequestPayload(JsonNode bodyNode) {
if(bodyNode == null || bodyNode.isNull()){
return "";
}
String mode = bodyNode.get("mode").asText();
if(mode.equals("none")){
return "";
}
if(mode.equals("raw")){
return bodyNode.get("raw").asText();
}
if(mode.equals("formdata")){
ArrayNode formdata = (ArrayNode) bodyNode.get("formdata");
StringBuilder sb = new StringBuilder();
for(JsonNode node : formdata){
String type = node.get("type").asText();
if(type.equals("file")){
sb.append(node.get("key").asText()).append("=").append(node.get("src").asText()).append("&");
} else if(type.equals("text")){
sb.append(node.get("key").asText()).append("=").append(node.get("value").asText()).append("&");
}
}
if (sb.length() > 0) sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
if(mode.equals("urlencoded")){
ArrayNode urlencoded = (ArrayNode) bodyNode.get("urlencoded");
StringBuilder sb = new StringBuilder();
for(JsonNode node : urlencoded){
sb.append(node.get("key").asText()).append("=").append(node.get("value").asText()).append("&");
}
if (sb.length() > 0) sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
if(mode.equals("graphql")){
return bodyNode.get("graphql").toPrettyString();
}
if(mode.equals("file")){
return bodyNode.get("file").get("src").asText();
}
return bodyNode.toPrettyString();
}

private static String getContentType(JsonNode request, JsonNode response, Map<String, String> responseHeadersMap) {
if(responseHeadersMap.containsKey("content-type")){
return responseHeadersMap.get("content-type");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
id: CORS_MISCONFIGURATION_INVALID_ORIGIN
info:
name: "Invalid Origin CORS Misconfiguration Detection"
description: >
"Detects misconfigured Cross-Origin Resource Sharing (CORS) settings by checking for invalid origin values, preventing unauthorized access."
details: >
"This test detects misconfigurations in Cross-Origin Resource Sharing (CORS) settings by checking for invalid origin values."
"It verifies that only allowed domains are listed as origins, preventing unauthorized access to sensitive resources. This test helps ensure proper security and protects against potential CORS-related vulnerabilities and data breaches."
impact: >
"A misconfigured CORS can have significant impact on web application security."
"If invalid origin values are not properly handled, it may allow unauthorized access to sensitive resources, leading to"
"data breaches, cross-site scripting (XSS) attacks, or unauthorized data manipulation, compromising the integrity and confidentiality of the system."
category:
name: CORS
shortName: CORS Misconfiguration
displayName: Cross-Origin Resource Sharing (CORS)
subCategory: CORS_MISCONFIGURATION_INVALID_ORIGIN
severity: HIGH
tags:
- Business logic
- OWASP top 10
- HackerOne top 10
references:
- "https://crashtest-security.com/cors-misconfiguration/"

auth:
authenticated: true

api_selection_filters:
response_code:
gte: 200
lt: 300

wordLists:
invalid_cors_origin:
- evil.com
- "`evil.com"
- "1221"

execute:
type: single
requests:
- req:
- add_header:
origin: ${invalid_cors_origin}

validate:
response_code:
gte: 200
lt: 300
response_headers:
and:
- for_one:
key:
contains_either: access-control-allow-origin
value:
contains_either: ${invalid_cors_origin}
- for_one:
key:
contains_either: access-control-allow-credentials
value:
contains_either: "true"
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
id: CORS_MISCONFIGURATION_WHITELIST_ORIGIN
info:
name: "CORS Whitelist Origin Validation"
description: "Validates the Cross-Origin Resource Sharing (CORS) whitelist, ensuring only authorized origins are included, enhancing application security."
details: >
"This test validates the configuration of Cross-Origin Resource Sharing (CORS) by exploiting the whitelist of allowed origins."
"It ensures that only authorized domains are included in the whitelist, preventing potential security risks and unauthorized access to resources, bolstering the overall security posture of the application"
impact: >
"A misconfigured CORS can have significant impact on web application security."
"If invalid origin values are not properly handled, it may allow unauthorized access to sensitive resources, leading to"
"data breaches, cross-site scripting (XSS) attacks, or unauthorized data manipulation, compromising the integrity and confidentiality of the system."
category:
name: CORS
shortName: CORS Misconfiguration
displayName: Cross-Origin Resource Sharing (CORS)
subCategory: CORS_MISCONFIGURATION_WHITELIST_ORIGIN
severity: HIGH
tags:
- Business logic
- OWASP top 10
- HackerOne top 10
references:
- "https://crashtest-security.com/cors-misconfiguration/"

auth:
authenticated: true

api_selection_filters:
response_code:
gte: 200
lt: 300
request_headers:
for_one:
key:
eq: Host
value:
extract: host_val

execute:
type: single
requests:
- req:
- add_header:
origin: ${host_val}.evil.com

validate:
response_code:
gte: 200
lt: 300
response_headers:
and:
- for_one:
key:
contains_either: access-control-allow-origin
value:
contains_either: ${host_val}.evil.com
- for_one:
key:
contains_either: access-control-allow-credentials
value:
contains_either: "true"
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
id: CSRF_LOGIN_ATTACK
info:
name: "CSRF Login attack"
description: "Hackers trick users to log into their account by forging requests, exploiting server authentication."
details: >
"A login CSRF attack involves hackers tricking users into logging into an attacker-controlled account."
"By forging a request using their credentials and submitting it to the victim's browser, the server mistakenly authenticates the request, granting access to the attacker's account."
impact: >
"Depending on the user account and information exposed, the impacts of an attack range from mild to severe."
"Some consequences of a successful login CSRF attack include: Deployment of malicious code, Unauthorized financial transactions and Data breach and sensitive information exposure"
category:
name: NO_AUTH
shortName: Broken Authentication
displayName: Broken User Authentication (BUA)
subCategory: CSRF_LOGIN_ATTACK
severity: LOW
tags:
- Business logic
- OWASP top 10
- HackerOne top 10
references:
- "https://crashtest-security.com/csrf-login-attack/"
- "https://www.invicti.com/web-vulnerability-scanner/vulnerabilities/cross-site-request-forgery-in-login-form-invicti/"

api_selection_filters:
response_code:
gte: 200
lt: 300
url:
contains_either:
- login
- signin
- sign-in
- log-in
request_payload:
for_one:
key:
contains_either:
- password
- pwd
- pass
- passwd
request_headers:
for_one:
key:
contains_either: cookie
extract: header_key

execute:
type: single
requests:
- req:
- delete_header: ${header_key}

validate:
response_code:
gte: 200
lt: 300
response_payload:
percentage_match:
gt: 80
length:
gt: 0
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ execute:
payload_location_key: http:https://evil.com/?p=${payload_location_value}
- modify_header:
payload_location_key: http:https://evil.com/?p=${payload_location_value}
- follow_redirect: false


validate:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
id: REMOVE_CSRF
info:
name: "CSRF test by removing csrf token"
description: "Assessing the system's vulnerability by removing the CSRF token to determine if unauthorized actions can be performed."
details: >
"Evaluating the effectiveness of the web application's CSRF protection mechanism by intentionally removing the CSRF token"
"and assessing if unauthorized actions can be successfully executed, potentially exposing the system to security risks and breaches."
impact: >
"Successful execution of unauthorized actions due to the absence of CSRF token may result in severe consequences,"
"such as unauthorized data modification, account hijacking, or sensitive information disclosure,"
"highlighting critical vulnerabilities and emphasizing the need for robust CSRF protection measures."
category:
name: NO_AUTH
shortName: Broken Authentication
displayName: Broken User Authentication (BUA)
subCategory: REMOVE_CSRF
severity: HIGH
tags:
- Business logic
- OWASP top 10
- HackerOne top 10
references:
- "https://portswigger.net/web-security/csrf"
- "https://owasp.org/www-community/attacks/csrf"

api_selection_filters:
response_code:
gte: 200
lt: 300
or:
- request_headers:
for_one:
key:
contains_either: csrf
extract: csrf_key
- request_payload:
for_one:
key:
contains_either: csrf
extract: csrf_key
- query_param:
for_one:
key:
contains_either: csrf
extract: csrf_key

execute:
type: single
requests:
- req:
- delete_header: ${csrf_key}
- delete_body_param: ${csrf_key}
- delete_query_param: ${csrf_key}

validate:
response_code:
gte: 200
lt: 300
response_payload:
percentage_match:
gt: 80
length:
gt: 0
Loading

0 comments on commit afbe75e

Please sign in to comment.