Skip to content

Commit

Permalink
Merge pull request #1016 from akto-api-security/feature_var_substitui…
Browse files Browse the repository at this point in the history
…on_override_url

Feature var substituion override url
  • Loading branch information
ayushaga14 authored Apr 17, 2024
2 parents 6c9af33 + a2895d3 commit 1c9294d
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 41 deletions.
5 changes: 5 additions & 0 deletions apps/dashboard/src/main/java/com/akto/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ public static boolean isValidURL(String url) {
new URL(url).toURI();
return true;
} catch (MalformedURLException | URISyntaxException e) {
Pattern pattern = Pattern.compile("\\$\\{[^}]*\\}");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
return true;
}
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.akto.dao.billing.OrganizationsDao;
import com.akto.dao.billing.TokensDao;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.akto.dao.CustomAuthTypeDao;
import com.akto.dao.context.Context;
Expand Down Expand Up @@ -44,12 +46,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.json.JSONObject;

Expand Down Expand Up @@ -78,7 +74,7 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map<String, Obje
List<CustomAuthType> customAuthTypes, boolean debug, List<TestingRunResult.TestLog> testLogs,
Memory memory) {
List<GenericTestResult> result = new ArrayList<>();

ExecutionListBuilder executionListBuilder = new ExecutionListBuilder();
List<ExecutorNode> executorNodes = new ArrayList<>();
ExecutionOrderResp executionOrderResp = executionListBuilder.parseExecuteOperations(node, executorNodes);
Expand Down Expand Up @@ -178,35 +174,6 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map<String, Obje
break;
}
try {

// change host header in case of override URL ( if not already changed by test template )
try {
List<String> originalHostHeaders = rawApi.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>());
List<String> attemptHostHeaders = testReq.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>());

if (!originalHostHeaders.isEmpty()
&& originalHostHeaders.get(0) != null
&& !attemptHostHeaders.isEmpty()
&& attemptHostHeaders.get(0) != null
&& originalHostHeaders.get(0).equals(attemptHostHeaders.get(0))
&& testingRunConfig != null
&& !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) {

String url = ApiExecutor.prepareUrl(testReq.getRequest(), testingRunConfig);
URI uri = new URI(url);
String host = uri.getHost();
if (uri.getPort() != -1) {
host += ":" + uri.getPort();
}
testReq.getRequest().getHeaders().put(_HOST, Collections.singletonList(host));
}

} catch (Exception e) {
testLogs.add(new TestingRunResult.TestLog(TestingRunResult.TestLogType.ERROR, "unable to update host header for overridden test URL"));
loggerMaker.errorAndAddToDb(e,"unable to update host header for overridden test URL",
LogDb.TESTING);
}

// follow redirects = true for now
testResponse = ApiExecutor.sendRequest(testReq.getRequest(), followRedirect, testingRunConfig, debug, testLogs);
requestSent = true;
Expand Down Expand Up @@ -237,6 +204,60 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map<String, Obje
return yamlTestResult;
}

public void overrideTestUrl(RawApi rawApi, TestingRunConfig testingRunConfig) {
try {
String url = "";
loggerMaker.infoAndAddToDb("override url received - " + testingRunConfig.getOverriddenTestAppUrl(), LogDb.TESTING);
List<String> originalHostHeaders = rawApi.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>());
if (!originalHostHeaders.isEmpty() && testingRunConfig != null
&& !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) {

Pattern pattern = Pattern.compile("\\$\\{[^}]*\\}");
Matcher matcher = pattern.matcher(testingRunConfig.getOverriddenTestAppUrl());
if (matcher.find()) {
String match = matcher.group(0);
match = match.substring(2, match.length());
match = match.substring(0, match.length() - 1);
String[] params = match.split("\\+");
for (int i = 0; i < params.length; i++) {
url += resolveParam(params[i], rawApi);
}
testingRunConfig.setOverriddenTestAppUrl(url);
} else {
url = testingRunConfig.getOverriddenTestAppUrl();
}

String newUrl = ApiExecutor.replacePathFromConfig(rawApi.getRequest().getUrl(), testingRunConfig);
URI uri = new URI(newUrl);
String host = uri.getHost();
if (uri.getPort() != -1) {
host += ":" + uri.getPort();
}
rawApi.getRequest().getHeaders().put(_HOST, Collections.singletonList(host));
rawApi.getRequest().setUrl(newUrl);

}

} catch (Exception e) {
//testLogs.add(new TestingRunResult.TestLog(TestingRunResult.TestLogType.ERROR, "unable to update host header for overridden test URL"));
loggerMaker.errorAndAddToDb(e,"unable to update host header for overridden test URL",
LogDb.TESTING);
}
}

public String resolveParam(String param, RawApi rawApi) {
param = param.trim();
String[] params = param.split("\\.");

if (params.length == 1) {
return params[0];
}

String key = params[params.length - 1];
String val = rawApi.getRequest().getHeaders().get(key).get(0);
return val;
}

private void overrideAuth(RawApi rawApi, AuthMechanism authMechanism) {
List<AuthParam> authParams = authMechanism.getAuthParams();
if (authParams == null || authParams.isEmpty()) {
Expand Down
8 changes: 3 additions & 5 deletions apps/testing/src/main/java/com/akto/testing/TestExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.akto.store.AuthMechanismStore;
import com.akto.store.SampleMessageStore;
import com.akto.store.TestingUtil;
import com.akto.test_editor.execution.Executor;
import com.akto.test_editor.execution.VariableResolver;
import com.akto.testing.yaml_tests.YamlTestTemplate;
import com.akto.testing_issues.TestingIssuesHandler;
Expand All @@ -43,11 +44,6 @@
import com.mongodb.MongoInterruptedException;
import org.apache.commons.lang3.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import com.mongodb.client.model.Sorts;
import com.mongodb.client.model.Updates;
import com.mongodb.client.model.*;

import org.bson.conversions.Bson;
Expand Down Expand Up @@ -675,6 +671,8 @@ public TestingRunResult runTestNew(ApiInfo.ApiInfoKey apiInfoKey, ObjectId testR
List<CustomAuthType> customAuthTypes = testingUtil.getCustomAuthTypes();
// TestingUtil -> authMechanism
// TestingConfig -> auth
com.akto.test_editor.execution.Executor executor = new Executor();
executor.overrideTestUrl(rawApi, testingRunConfig);
YamlTestTemplate yamlTestTemplate = new YamlTestTemplate(apiInfoKey,filterNode, validatorNode, executorNode,
rawApi, varMap, auth, testingUtil.getAuthMechanism(), testExecutionLogId, testingRunConfig, customAuthTypes, testConfig.getStrategy());
YamlTestResult testResults = yamlTestTemplate.run(debug, testLogs);
Expand Down
46 changes: 46 additions & 0 deletions libs/utils/src/main/java/com/akto/testing/ApiExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,52 @@ public static String replaceHostFromConfig(String url, TestingRunConfig testingR
return url;
}

public static String replacePathFromConfig(String url, TestingRunConfig testingRunConfig) {
if (testingRunConfig != null && !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) {
URI typedUrl = null;
try {
typedUrl = new URI(url);

} catch (URISyntaxException e) {
loggerMaker.errorAndAddToDb(e, "error converting req url to uri " + url, LogDb.TESTING);
throw new RuntimeException(e);
}

String newUrl = testingRunConfig.getOverriddenTestAppUrl();

URI newUri = null;
try {
newUri = new URI(newUrl);

} catch (URISyntaxException e) {
loggerMaker.errorAndAddToDb(e, "error converting override url to uri " + url, LogDb.TESTING);
throw new RuntimeException(e);
}

String newPath = newUri.getPath();

if (newPath.equals("") || newPath.equals("/")) {
newPath = typedUrl.getPath();
}

String newHost = newUri.getHost();
if (newUri.getHost().equals("")) {
newHost = typedUrl.getHost();
}

try {
String newScheme = newUri.getScheme() == null ? typedUrl.getScheme() : newUri.getScheme();
int newPort = newUri.getPort() == -1 ? typedUrl.getPort() : newUri.getPort();

url = new URI(newScheme, null, newHost, newPort, newPath, typedUrl.getQuery(), typedUrl.getFragment()).toString();
} catch (URISyntaxException e) {
loggerMaker.errorAndAddToDb(e, "error building new url using override url", LogDb.TESTING);
throw new RuntimeException(e);
}
}
return url;
}

public static String prepareUrl(OriginalHttpRequest request, TestingRunConfig testingRunConfig) throws Exception{
String url = request.getUrl();
url = url.trim();
Expand Down

0 comments on commit 1c9294d

Please sign in to comment.