Skip to content

Commit

Permalink
Merge pull request #1010 from akto-api-security/master
Browse files Browse the repository at this point in the history
back merge
  • Loading branch information
avneesh-akto authored Apr 15, 2024
2 parents 4199041 + 5292667 commit d1fff6e
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -52,6 +53,7 @@ public class AccountAction extends UserAction {

public static final int MAX_NUM_OF_LAMBDAS_TO_FETCH = 50;
private static final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private static final ExecutorService service = Executors.newFixedThreadPool(1);

@Override
public String execute() {
Expand Down Expand Up @@ -309,7 +311,11 @@ public void run() {
DaoInit.createIndices();
Main.insertRuntimeFilters();
RuntimeListener.initialiseDemoCollections();
RuntimeListener.addSampleData();
service.submit(() ->{
Context.accountId.set(newAccountId);
loggerMaker.infoAndAddToDb("updating vulnerable api's collection for new account " + newAccountId, LogDb.DASHBOARD);
RuntimeListener.addSampleData();
});
AccountSettingsDao.instance.updateOnboardingFlag(true);
InitializerListener.insertPiiSources();

Expand Down
37 changes: 37 additions & 0 deletions apps/dashboard/src/main/java/com/akto/action/LoginAction.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.akto.action;

import com.akto.dao.BackwardCompatibilityDao;
import com.akto.dao.SignupDao;
import com.akto.dao.SingleTypeInfoDao;
import com.akto.dao.UsersDao;
import com.akto.dao.context.Context;
import com.akto.dto.BackwardCompatibility;
import com.akto.dto.Config;
import com.akto.dto.SignupInfo;
import com.akto.dto.SignupUserInfo;
import com.akto.dto.User;
import com.akto.listener.RuntimeListener;
import com.akto.log.LoggerMaker.LogDb;
import com.akto.utils.Token;
import com.akto.utils.JWT;
import com.mongodb.BasicDBObject;
Expand All @@ -29,6 +33,8 @@
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.akto.filter.UserDetailsFilter.LOGIN_URI;

Expand All @@ -42,6 +48,7 @@ public class LoginAction implements Action, ServletResponseAware, ServletRequest
private static final Logger logger = LoggerFactory.getLogger(LoginAction.class);

public static final String REFRESH_TOKEN_COOKIE_NAME = "refreshToken";
private static final ExecutorService service = Executors.newFixedThreadPool(1);
public BasicDBObject getLoginResult() {
return loginResult;
}
Expand Down Expand Up @@ -93,10 +100,37 @@ public String execute() throws IOException {
//For the case when no account exists, the user will get access to 1_000_000 account
String accountIdStr = user.getAccounts().keySet().isEmpty() ? "1000000" : user.getAccounts().keySet().iterator().next();
int accountId = StringUtils.isNumeric(accountIdStr) ? Integer.parseInt(accountIdStr) : 1_000_000;
try {
service.submit(() ->{
triggerVulnColUpdation(user);
});
} catch (Exception e) {
logger.error("error updating vuln collection ", e);
}
decideFirstPage(loginResult, accountId);
return result;
}

private static void triggerVulnColUpdation(User user) {
for (String accountIdStr: user.getAccounts().keySet()) {
int accountId = Integer.parseInt(accountIdStr);
Context.accountId.set(accountId);
logger.info("updating vulnerable api's collection for account " + accountId);
try {
BackwardCompatibility backwardCompatibility = BackwardCompatibilityDao.instance.findOne(new BasicDBObject());
if (backwardCompatibility.getVulnerableApiUpdationVersionV1() == 0) {
RuntimeListener.addSampleData();
}
BackwardCompatibilityDao.instance.updateOne(
Filters.eq("_id", backwardCompatibility.getId()),
Updates.set(BackwardCompatibility.VULNERABLE_API_UPDATION_VERSION_V1, Context.now())
);
} catch (Exception e) {
logger.error("error updating vulnerable api's collection for account " + accountId + " " + e.getMessage());
}
}
}

private void decideFirstPage(BasicDBObject loginResult, int accountId){
Context.accountId.set(accountId);
long count = SingleTypeInfoDao.instance.getEstimatedCount();
Expand Down Expand Up @@ -157,6 +191,9 @@ public static String loginUser(User user, HttpServletResponse servletResponse, b
)
);
}
service.submit(() ->{
triggerVulnColUpdation(user);
});
return Action.SUCCESS.toUpperCase();
} catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException e) {
e.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void accept(Account account) {

try {
initialiseDemoCollections();
addSampleData();
//addSampleData();
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e,"Error while initialising demo collections: " + e, LoggerMaker.LogDb.DASHBOARD);
}
Expand Down 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 @@ -44,10 +44,6 @@
padding-left: 10px ;
}

.new-diff .view-lines{
background: #FAFBFB !important;
}

.new-diff .monaco-hover{
background-color: #FFF5EA !important;
border-radius: 2px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@
word-break: break-all !important;
}

.test-title .Polaris-Text--break {
word-break: normal !important;
}

.Polaris-Frame__Skip{
visibility: hidden !important;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const TestEditor = () => {
const setVulnerableRequestMap = TestEditorStore(state => state.setVulnerableRequestMap)
const setDefaultRequest = TestEditorStore(state => state.setDefaultRequest)
const setActive = PersistStore(state => state.setActive)
const selectedSampleApi = TestEditorStore(state => state.selectedSampleApi)

const [loading, setLoading] = useState(true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ const SampleApi = () => {
const selectedTest = TestEditorStore(state => state.selectedTest)
const vulnerableRequestsObj = TestEditorStore(state => state.vulnerableRequestsMap)
const defaultRequest = TestEditorStore(state => state.defaultRequest)
const selectedSampleApi = TestEditorStore(state => state.selectedSampleApi)
const setSelectedSampleApi = TestEditorStore(state => state.setSelectedSampleApi)
const selectedSampleApi = PersistStore(state => state.selectedSampleApi)
const setSelectedSampleApi = PersistStore(state => state.setSelectedSampleApi)

const tabs = [{ id: 'request', content: 'Request' }, { id: 'response', content: 'Response'}];
const mapCollectionIdToName = func.mapCollectionIdToName(allCollections)

useEffect(()=>{
let testId = selectedTest.value
let selectedUrl = selectedSampleApi.hasOwnProperty(testId) ? selectedSampleApi[testId] : vulnerableRequestsObj?.[testId]
let selectedUrl = Object.keys(selectedSampleApi).length > 0 ? selectedSampleApi : vulnerableRequestsObj?.[testId]
setSelectedCollectionId(null)
setCopyCollectionId(null)
setTestResult(null)
Expand Down Expand Up @@ -95,6 +95,8 @@ const SampleApi = () => {
localEditorData = transform.formatData(sampleData?.responseJson, "http")
}
setEditorData({message: localEditorData})
}else{
setEditorData({message: ''})
}
}

Expand Down Expand Up @@ -137,23 +139,26 @@ const SampleApi = () => {
},0)

setSelected(0)
}else{
setEditorData({message: ''})
}
}else{
setEditorData({message: ''})
}
}

const toggleSelectApiActive = () => setSelectApiActive(prev => !prev)
const saveFunc = () =>{
setSelectedApiEndpoint(copySelectedApiEndpoint)
let copySampleApiObj = {...selectedSampleApi}
const urlObj = func.toMethodUrlObject(copySelectedApiEndpoint)
copySampleApiObj[selectedTest.value] = {
const sampleApi = {
apiCollectionId :copyCollectionId,
url: urlObj.url,
method:{
"_name": urlObj.method
}
}
setSelectedSampleApi(copySampleApiObj)
setSelectedSampleApi(sampleApi)
setSelectedCollectionId(copyCollectionId)
toggleSelectApiActive()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ const YamlEditor = ({ fetchAllTests }) => {
const setTestsObj = TestEditorStore(state => state.setTestsObj)
const setCurrentContent = TestEditorStore(state => state.setCurrentContent)

const selectedSampleApi = TestEditorStore(state => state.selectedSampleApi)
const setSelectedSampleApi = TestEditorStore(state => state.setSelectedSampleApi)

const [ isEdited, setIsEdited ] = useState(false)
const [ editorInstance, _setEditorInstance ] = useState()
const editorInstanceRef = useRef(editorInstance)
Expand Down Expand Up @@ -72,9 +69,6 @@ const YamlEditor = ({ fetchAllTests }) => {
isError: false,
message: "Test saved successfully!"
})
let newUrlObj = {...selectedSampleApi}
newUrlObj[addTestTemplateResponse.finalTestId] = selectedSampleApi[selectedTest.value];
setSelectedSampleApi(newUrlObj);
navigate(`/dashboard/test-editor/${addTestTemplateResponse.finalTestId}`)
fetchAllTests()
} catch(error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ let testEditorStore = (set)=>({
setCurrentContent:(currentContent)=>{
set({currentContent: currentContent})
},

selectedSampleApi: {},
setSelectedSampleApi: (selectedSampleApi) => set({selectedSampleApi: selectedSampleApi})
})

testEditorStore = devtools(testEditorStore)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function TestRunResultFlyout(props) {
<div style={{display: 'flex', justifyContent: "space-between", gap:"24px", padding: "16px", paddingTop: '0px'}}>
<VerticalStack gap={"2"}>
<Box width="100%">
<div style={{display: 'flex', gap: '4px'}}>
<div style={{display: 'flex', gap: '4px'}} className='test-title'>
<Text variant="headingSm" alignment="start" breakWord>{selectedTestRunResult?.name}</Text>
{severity.length > 0 ? <Box><Badge size="small" status={func.getTestResultStatus(severity)}>{severity}</Badge></Box> : null}
</div>
Expand Down
Loading

0 comments on commit d1fff6e

Please sign in to comment.