Skip to content

Commit

Permalink
Merge pull request #1006 from akto-api-security/feature_req_header_vu…
Browse files Browse the repository at this point in the history
…ln_col

Feature req header vuln col
  • Loading branch information
ayushaga14 authored Apr 15, 2024
2 parents 461f196 + d9944d4 commit ad9d8b9
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public static void addSampleData() {
for (SingleTypeInfo singleTypeInfo: params) {
urlList.add(singleTypeInfo.getUrl());
}
if (urlList.size() != 190) {
if (urlList.size() != 194) {
Utils.pushDataToKafka(VULNERABLE_API_COLLECTION_ID, "", result, new ArrayList<>(), true);
}

Expand Down
130 changes: 130 additions & 0 deletions apps/dashboard/src/main/resources/SampleApiData.json
Original file line number Diff line number Diff line change
Expand Up @@ -4490,5 +4490,135 @@
"responseHeaders": {},
"statusCode": 200
}
},
{
"id": "CONTENT_TYPE_HEADER_MISSING",
"sampleData": {
"method": "GET",
"requestPayload": "",
"responsePayload": "{\"courses\": [{\"courseId\": \"CS101\", \"name\": \"Computer Science\", \"duration\": \"4 years\", \"faculty\": \"PROF-404\", \"description\": \"This course provides in-depth knowledge of computer science principles and applications.\"}, {\"courseId\": \"ENG201\", \"name\": \"English\", \"duration\": \"3 years\", \"faculty\": \"PROF-202\", \"description\": \"Explore the world of literature and develop critical thinking and analytical skills.\"}, {\"courseId\": \"MAT301\", \"name\": \"Mathematics\", \"duration\": \"3 years\", \"faculty\": \"PROF-505\", \"description\": \"Study advanced mathematical concepts and their real-world applications.\"}]}",
"requestHeaders": "{\"Authorization\":\"JWT eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJBa3RvIiwic3ViIjoibG9naW4iLCJzaWduZWRVcCI6InRydWUiLCJ1c2VybmFtZSI6InJpc2hhdi5zb2xhbmtpQGFrdG8uaW8iLCJpYXQiOjE2ODg3MTMzNTUsImV4cCI6MTY4ODcxNDI1NX0.ToSrgQdEWaTVBphY9QMPBmo1zWgaDt_2zRlFb4gLYcgn3x58ClnTciRXN--9 LeoKojWo466S2rDDK8KH3IhR7gTDKk9ihKfLaVoKIg7M7RaHxFgp - vtjWenFcR6IBqLXqYh_kCqBFDH3hjrbD1Qtoaieu_L1rtJFwqz2xoIZP0VEmTPXT4vxT6yoVlbgloROzu1cJFGnoFQm69OUNHpCLf9S_7Qs - 9 eV2V - AlzeClfMnblTqhQP_s4znPit2Ik0ypNIH - mEwgxL - coWVmphuFYy5uG5c2Z4F4te7r_QP9jlOVYFjwB6_9gQSwi1lrm8qKdNml1UKnh4NNizc1878oQ\", \"Content-Length\": \"2\"}",
"responseHeaders": "",
"status": "OK",
"statusCode": "200",
"path": "/api/college/course-list"
},
"testData": {
"method": "GET",
"url": "/api/college/course-list",
"responsePayload": {
"courses": {
"courseId_1": "CS101",
"courseId_2": "CS102",
"courseId_3": "CS103",
"courseId_4": "CS104",
"courseId_5": "CS105"
}
},
"responseHeaders": {
"Server": "Apache/2.4.18 (Ubuntu)"
},
"statusCode": 200
}
},
{
"id": "FIREBASE_UNAUTHENTICATED",
"sampleData": {
"method": "GET",
"requestPayload": "",
"responsePayload": "{\"d1\" : \"CSE\", \"d2\": \"ECE\", \"d3\": \"IT\"}",
"requestHeaders": "{\"Authorization\":\"JWT eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJBa3RvIiwic3ViIjoibG9naW4iLCJzaWduZWRVcCI6InRydWUiLCJ1c2VybmFtZSI6InJpc2hhdi5zb2xhbmtpQGFrdG8uaW8iLCJpYXQiOjE2ODg3MTMzNTUsImV4cCI6MTY4ODcxNDI1NX0.ToSrgQdEWaTVBphY9QMPBmo1zWgaDt_2zRlFb4gLYcgn3x58ClnTciRXN--9 LeoKojWo466S2rDDK8KH3IhR7gTDKk9ihKfLaVoKIg7M7RaHxFgp - vtjWenFcR6IBqLXqYh_kCqBFDH3hjrbD1Qtoaieu_L1rtJFwqz2xoIZP0VEmTPXT4vxT6yoVlbgloROzu1cJFGnoFQm69OUNHpCLf9S_7Qs - 9 eV2V - AlzeClfMnblTqhQP_s4znPit2Ik0ypNIH - mEwgxL - coWVmphuFYy5uG5c2Z4F4te7r_QP9jlOVYFjwB6_9gQSwi1lrm8qKdNml1UKnh4NNizc1878oQ\", \"Content-Type\": \"application/json\", \"Content-Length\": \"2\"}",
"responseHeaders": "",
"status": "OK",
"statusCode": "200",
"path": "/api/college/info/departments/branch"
},
"testData": {
"method": "GET",
"url": "/api/college/info/departments/branch.json",
"responsePayload": {
"d1": {
"id": "CSE",
"name": "Computer Science"
},
"d2": {
"id": "ECE",
"name": "Electronics and Communication"
},
"d3": {
"id": "IT",
"name": "Information Technology"
}
},
"responseHeaders": {},
"statusCode": 200
}
},
{
"id": "PASSWD_CHANGE_BRUTE_FORCE",
"sampleData": {
"method": "POST",
"requestPayload": "{\"username\": \"STUD-9965\", \"password\":\"qwerty123\"}",
"requestHeaders": "{\"Authorization\":\"JWT eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJBa3RvIiwic3ViIjoibG9naW4iLCJzaWduZWRVcCI6InRydWUiLCJ1c2VybmFtZSI6InJpc2hhdi5zb2xhbmtpQGFrdG8uaW8iLCJpYXQiOjE2ODg3MTMzNTUsImV4cCI6MTY4ODcxNDI1NX0.ToSrgQdEWaTVBphY9QMPBmo1zWgaDt_2zRlFb4gLYcgn3x58ClnTciRXN--9 LeoKojWo466S2rDDK8KH3IhR7gTDKk9ihKfLaVoKIg7M7RaHxFgp - vtjWenFcR6IBqLXqYh_kCqBFDH3hjrbD1Qtoaieu_L1rtJFwqz2xoIZP0VEmTPXT4vxT6yoVlbgloROzu1cJFGnoFQm69OUNHpCLf9S_7Qs - 9 eV2V - AlzeClfMnblTqhQP_s4znPit2Ik0ypNIH - mEwgxL - coWVmphuFYy5uG5c2Z4F4te7r_QP9jlOVYFjwB6_9gQSwi1lrm8qKdNml1UKnh4NNizc1878oQ\", \"HOST\": \"vulnerableapi.com\", \"Content-Type\": \"application/json\", \"Content-Length\": \"2\"}",
"responsePayload": "{\"status\": \"Password change successful\"}",
"responseHeaders": "",
"status": "OK",
"statusCode": "200",
"path": "/api/college/erp/login/change-password"
},
"testData": {
"method": "POST",
"url": "/api/college/erp/login/change-password",
"responsePayload": {
"status": "Password change successful"
},
"responseHeaders": {},
"statusCode": 200
}
},
{
"id": "BOLA_COOKIE_FUZZING",
"sampleData": {
"method": "GET",
"requestPayload": "{\"email\": \"user6@example.com\",\"role\": \"user\"}",
"requestHeaders": "{\"Authorization\":\"JWT eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJBa3RvIiwic3ViIjoibG9naW4iLCJzaWduZWRVcCI6InRydWUiLCJ1c2VybmFtZSI6InJpc2hhdi5zb2xhbmtpQGFrdG8uaW8iLCJpYXQiOjE2ODg3MTMzNTUsImV4cCI6MTY4ODcxNDI1NX0.ToSrgQdEWaTVBphY9QMPBmo1zWgaDt_2zRlFb4gLYcgn3x58ClnTciRXN--9 LeoKojWo466S2rDDK8KH3IhR7gTDKk9ihKfLaVoKIg7M7RaHxFgp-vtjWenFcR6IBqLXqYh_kCqBFDH3hjrbD1Qtoaieu_L1rtJFwqz2xoIZP0VEmTPXT4vxT6yoVlbgloROzu1cJFGnoFQm69OUNHpCLf9S_7Qs-9eV2V-AlzeClfMnblTqhQP_s4znPit2Ik0ypNIH-mEwgxL-coWVmphuFYy5uG5c2Z4F4te7r_QP9jlOVYFjwB6_9gQSwi1lrm8qKdNml1UKnh4NNizc1878oQ\", \"HOST\": \"vulnerableapi.com\", \"cookie\": \"refreshToken=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJBa3RvIiwic3ViIjoicmVmcmVzaFRva2VuIiwic2lnbmVasdkSDG3jsnVlIiwidjknbjhksd8757dfsjkgDFG93nQGFrdG8uaW8iLCJpYXQiOjE2ODk2OTg0MDgsImV4cCI6MTY5MDIxNjgwOH0.i4YOfDCn4W3weTYqU5M3zaB37L4DHRUaFc91XVzD0_WOYRlTETrzFyLRpMETP7GrttSE79DyFDIN9nVgtuiAOrcLafyZUZsbV9oqLaNxEHx3vcyOQpg7Br7AUPxzqnIyZs_vxdmnkewRoxaeMifhlXuhIvORCoLZRHBgLX66CuJNqBwQy6zO3W0DcdgFN0DOWeQulYN2m8KLuNVDzHswq0s9jOWLPEwVBwlQc-sdf3sFKAoe9rewKNMSA4ptWOds6tqphBs0RYyaE4S_HFywT8mmMb8mer7fdzFqTEXfyKFzEFbI2M9k2_kpASyd6uvl_Cdk22QSIZBzjRMVo3VOLWgg; intercom-device-id-xjvl0z2h=25750e91-1931-42e2-a319-8b7289df6800\"}",
"responsePayload": "{\"flower\": \"Lilium\", \"number\": \"274\"}",
"responseHeaders": "",
"status": "OK",
"statusCode": "200",
"path": "/api/college/garden/123653"
},
"testData": {
"method": "GET",
"url": "/api/college/garden/123653",
"responsePayload": {
"flower": "Lilium",
"number": "274"
},
"responseHeaders": {},
"statusCode": 200
}
},
{
"id": "HEAD_METHOD_TEST",
"sampleData": {
"method": "GET",
"requestPayload": "",
"responsePayload": "{\"message\": \"Redirecting...\"}",
"requestHeaders": "{\"Authorization\":\"JWT eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJBa3RvIiwic3ViIjoibG9naW4iLCJzaWduZWRVcCI6InRydWUiLCJ1c2VybmFtZSI6InJpc2hhdi5zb2xhbmtpQGFrdG8uaW8iLCJpYXQiOjE2ODg3MTMzNTUsImV4cCI6MTY4ODcxNDI1NX0.ToSrgQdEWaTVBphY9QMPBmo1zWgaDt_2zRlFb4gLYcgn3x58ClnTciRXN--9 LeoKojWo466S2rDDK8KH3IhR7gTDKk9ihKfLaVoKIg7M7RaHxFgp - vtjWenFcR6IBqLXqYh_kCqBFDH3hjrbD1Qtoaieu_L1rtJFwqz2xoIZP0VEmTPXT4vxT6yoVlbgloROzu1cJFGnoFQm69OUNHpCLf9S_7Qs - 9 eV2V - AlzeClfMnblTqhQP_s4znPit2Ik0ypNIH - mEwgxL - coWVmphuFYy5uG5c2Z4F4te7r_QP9jlOVYFjwB6_9gQSwi1lrm8qKdNml1UKnh4NNizc1878oQ\", \"Content-Type\": \"application/json\", \"Content-Length\": \"2\", \"X-CSRF-Token\": \"abcdef1234567890\"}",
"responseHeaders": "",
"status": "OK",
"statusCode": "302",
"path": "/api/college/head-endpoint"
},
"testData": {
"method": "HEAD",
"url": "/api/college/head-endpoint",
"responsePayload": {
"message": "Welcome to the collegeXYZ Portal"
},
"responseHeaders": {},
"statusCode": 200
}
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map<String, Obje
testRawApis.add(sampleRawApi.copy());
ExecutorAlgorithm executorAlgorithm = new ExecutorAlgorithm(sampleRawApi, varMap, authMechanism, customAuthTypes);
Map<Integer, ExecuteAlgoObj> algoMap = new HashMap<>();
ExecutorSingleRequest singleReq = executorAlgorithm.execute(executorNodes, 0, algoMap, testRawApis, false, 0);
ExecutorSingleRequest singleReq = executorAlgorithm.execute(executorNodes, 0, algoMap, testRawApis, false, 0, apiInfoKey);

if (!singleReq.getSuccess()) {
testRawApis = new ArrayList<>();
Expand Down Expand Up @@ -371,9 +371,9 @@ public TestResult validate(ExecutionResult attempt, RawApi rawApi, Map<String, O
return testResult;
}

public ExecutorSingleOperationResp invokeOperation(String operationType, Object key, Object value, RawApi rawApi, Map<String, Object> varMap, AuthMechanism authMechanism, List<CustomAuthType> customAuthTypes) {
public ExecutorSingleOperationResp invokeOperation(String operationType, Object key, Object value, RawApi rawApi, Map<String, Object> varMap, AuthMechanism authMechanism, List<CustomAuthType> customAuthTypes, ApiInfo.ApiInfoKey apiInfoKey) {
try {
ExecutorSingleOperationResp resp = runOperation(operationType, rawApi, key, value, varMap, authMechanism, customAuthTypes);
ExecutorSingleOperationResp resp = runOperation(operationType, rawApi, key, value, varMap, authMechanism, customAuthTypes, apiInfoKey);
return resp;
} catch(Exception e) {
return new ExecutorSingleOperationResp(false, "error executing executor operation " + e.getMessage());
Expand Down Expand Up @@ -544,7 +544,7 @@ private static BasicDBObject getBillingTokenForAuth() {
return bDObject;
}

public ExecutorSingleOperationResp runOperation(String operationType, RawApi rawApi, Object key, Object value, Map<String, Object> varMap, AuthMechanism authMechanism, List<CustomAuthType> customAuthTypes) {
public ExecutorSingleOperationResp runOperation(String operationType, RawApi rawApi, Object key, Object value, Map<String, Object> varMap, AuthMechanism authMechanism, List<CustomAuthType> customAuthTypes, ApiInfo.ApiInfoKey apiInfoKey) {
switch (operationType.toLowerCase()) {
case "send_ssrf_req":
String keyValue = key.toString().replaceAll("\\$\\{random_uuid\\}", "");
Expand Down Expand Up @@ -650,6 +650,9 @@ public ExecutorSingleOperationResp runOperation(String operationType, RawApi raw
}
removed = removeCustomAuth(rawApi, customAuthTypes) || removed ;
if (removed) {
if (apiInfoKey.getApiCollectionId() == 1111111111) {
Operations.addHeader(rawApi, Constants.AKTO_REMOVE_AUTH , "0");
}
return new ExecutorSingleOperationResp(true, "");
} else {
return new ExecutorSingleOperationResp(false, "header key not present");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import com.akto.dao.test_editor.TestEditorEnums;
import com.akto.dao.test_editor.TestEditorEnums.ExecutorOperandTypes;
import com.akto.dto.ApiInfo;
import com.akto.dto.CustomAuthType;
import com.akto.dto.RawApi;
import com.akto.dto.test_editor.ExecuteAlgoObj;
Expand Down Expand Up @@ -33,7 +34,7 @@ public ExecutorAlgorithm(RawApi sampleRawApi, Map<String, Object> varMap, AuthMe
public ExecutorAlgorithm(){
}

public ExecutorSingleRequest execute(List<ExecutorNode> executorNodes, int operationIndex, Map<Integer, ExecuteAlgoObj> algoMap, List<RawApi> rawApis, boolean expandRawApis, int rawapiInsertCount) {
public ExecutorSingleRequest execute(List<ExecutorNode> executorNodes, int operationIndex, Map<Integer, ExecuteAlgoObj> algoMap, List<RawApi> rawApis, boolean expandRawApis, int rawapiInsertCount, ApiInfo.ApiInfoKey apiInfoKey) {

if (operationIndex < 0 || operationIndex >= executorNodes.size()) {
return new ExecutorSingleRequest(true, "", rawApis, null);
Expand Down Expand Up @@ -92,7 +93,7 @@ public ExecutorSingleRequest execute(List<ExecutorNode> executorNodes, int opera
for (int i = 0; i < numberOfOperations; i++) {
if (!expandRawApis && rawApiIndex >= rawApis.size()) {
for (int j = 0; j < operationIndex; j++) {
executorSingleRequest = execute(executorNodes, j, algoMap, rawApis, true, numberOfOperations - i);
executorSingleRequest = execute(executorNodes, j, algoMap, rawApis, true, numberOfOperations - i, apiInfoKey);
if (!executorSingleRequest.getSuccess()) {
return executorSingleRequest;
}
Expand All @@ -110,7 +111,7 @@ public ExecutorSingleRequest execute(List<ExecutorNode> executorNodes, int opera
valIndex = (valIndex + 1)%valList.size();
}
}
ExecutorSingleOperationResp resp = executor.invokeOperation(executorNode.getOperationType(), key, val, rawApis.get(rawApiIndex), varMap, authMechanism, customAuthTypes);
ExecutorSingleOperationResp resp = executor.invokeOperation(executorNode.getOperationType(), key, val, rawApis.get(rawApiIndex), varMap, authMechanism, customAuthTypes, apiInfoKey);
if (!resp.getSuccess()) {
return new ExecutorSingleRequest(false, resp.getErrMsg(), null, false);
}
Expand All @@ -123,7 +124,7 @@ public ExecutorSingleRequest execute(List<ExecutorNode> executorNodes, int opera

algoMap.put(operationIndex, new ExecuteAlgoObj(numberOfOperations, keyIndex, valIndex, rawApis.size()));
if (!expandRawApis) {
executorSingleRequest = execute(executorNodes, operationIndex + 1, algoMap, rawApis, false, 0);
executorSingleRequest = execute(executorNodes, operationIndex + 1, algoMap, rawApis, false, 0, apiInfoKey);
}
return executorSingleRequest;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public NodeResult processNode(Node node, Map<String, Object> varMap, Boolean all

ExecutorAlgorithm executorAlgorithm = new ExecutorAlgorithm(sampleRawApi, varMap, authMechanism, customAuthTypes);
Map<Integer, ExecuteAlgoObj> algoMap = new HashMap<>();
ExecutorSingleRequest singleReq = executorAlgorithm.execute(executorNodes, 0, algoMap, rawApis, false, 0);
ExecutorSingleRequest singleReq = executorAlgorithm.execute(executorNodes, 0, algoMap, rawApis, false, 0, yamlNodeDetails.getApiInfoKey());

if (!singleReq.getSuccess()) {
rawApis = new ArrayList<>();
Expand All @@ -104,9 +104,11 @@ public NodeResult processNode(Node node, Map<String, Object> varMap, Boolean all
List<Integer> responseLenArr = new ArrayList<>();

for (RawApi testReq: rawApis) {
Map<String, List<String>> headers = testReq.fetchReqHeaders();
headers.put(Constants.AKTO_NODE_ID, Collections.singletonList(node.getId()));
testReq.modifyReqHeaders(headers);
if (yamlNodeDetails.getApiCollectionId() == 1111111111) {
Map<String, List<String>> headers = testReq.fetchReqHeaders();
headers.put(Constants.AKTO_NODE_ID, Collections.singletonList(node.getId()));
testReq.modifyReqHeaders(headers);
}
if (vulnerable) {
break;
}
Expand Down
1 change: 1 addition & 0 deletions libs/dao/src/main/java/com/akto/util/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ private Constants() {}
public static final String AKTO_ATTACH_FILE = "x-akto-attach-file";
public static final String AKTO_TOKEN_KEY = "x-akto-key";
public static final String AKTO_NODE_ID = "x-akto-node";
public static final String AKTO_REMOVE_AUTH= "x-akto-remove-auth";

}

0 comments on commit ad9d8b9

Please sign in to comment.