From f3c376470cf2d3e68663e864eb7fd1c2a6b3f2f7 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Thu, 7 Sep 2023 19:11:15 +0100 Subject: [PATCH 1/9] initial integration with auditWizard --- .../web/src/assets/images/audit_wizard.png | Bin 0 -> 3830 bytes packages/web/src/languages/en.json | 12 +- .../SubmissionContactInfo.tsx | 6 +- .../SubmissionDescriptions.tsx | 26 ++-- .../FormSteps/SubmissionDescriptions/utils.ts | 2 +- .../SubmissionProject/SubmissionProject.tsx | 4 +- .../SubmissionProcessed.tsx | 2 +- .../SubmissionReview/SubmissionReview.tsx | 20 ++- .../components/SubmissionReview/styles.ts | 2 + .../SubmissionFormPage/SubmissionFormPage.tsx | 137 +++++++++++++++++- .../Submissions/SubmissionFormPage/store.ts | 1 + .../Submissions/SubmissionFormPage/styles.ts | 27 ++++ .../submissionsService.api.ts | 6 +- .../Submissions/SubmissionFormPage/types.ts | 1 + 14 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 packages/web/src/assets/images/audit_wizard.png diff --git a/packages/web/src/assets/images/audit_wizard.png b/packages/web/src/assets/images/audit_wizard.png new file mode 100644 index 0000000000000000000000000000000000000000..86e959765c3b464205640f083bd95915a4aa5456 GIT binary patch literal 3830 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 submission will be sent to the committee who will process your submission.

The committee of the vault will respond within 12 hours to acknowledge the receipt of submission via the communication channel you provided.

", diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx index 296a78be4..efa33353e 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx @@ -13,7 +13,7 @@ import { StyledContactInfo } from "./styles"; export function SubmissionContactInfo() { const { t } = useTranslation(); const { address: account } = useAccount(); - const { submissionData, setSubmissionData, vault } = useContext(SubmissionFormContext); + const { submissionData, setSubmissionData, vault, allFormDisabled } = useContext(SubmissionFormContext); const isAuditCompetition = vault?.description?.["project-metadata"].type === "audit"; @@ -70,6 +70,7 @@ export function SubmissionContactInfo() { {t("Submissions.addGithubAccountConnectIssue")}

(); const isAuditSubmission = vault?.description?.["project-metadata"].type === "audit"; @@ -124,6 +124,7 @@ export function SubmissionDescriptions() { const { encryptedData, sessionKey } = encryptionResult; const submissionInfo = { + ref: submissionData.ref, decrypted, encrypted: encryptedData as string, }; @@ -178,6 +179,7 @@ export function SubmissionDescriptions() {
( (field.name, dirtyFields, defaultValues)} error={error} label={t("severity")} @@ -204,6 +207,7 @@ export function SubmissionDescriptions() { name={`descriptions.${index}.description`} render={({ field, fieldState: { error }, formState: { dirtyFields, defaultValues } }) => ( (field.name, dirtyFields, defaultValues)} error={error} colorable @@ -212,7 +216,7 @@ export function SubmissionDescriptions() { )} /> - {!submissionDescription.isEncrypted && ( + {!submissionDescription.isEncrypted && !allFormDisabled && ( )} - {controlledDescriptions.length > 1 && ( + {controlledDescriptions.length > 1 && !allFormDisabled && (
+ {!allFormDisabled && ( + + )}
diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/utils.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/utils.ts index d77d93a78..98925a0e9 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/utils.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/utils.ts @@ -88,7 +88,7 @@ export const getGithubIssueDescription = ( submissionData: ISubmissionData, description: ISubmissionsDescriptionsData["descriptions"][0] ) => { - return ` + return `${submissionData.ref === "audit-wizard" ? "***Submitted via auditwizard.io***\n" : ""} **Github username:** ${submissionData.contact?.githubUsername ? `@${submissionData.contact?.githubUsername}` : "--"} **Submission hash (on-chain):** ${submissionData.submissionResult?.transactionHash} **Severity:** ${description.severity} diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionProject/SubmissionProject.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionProject/SubmissionProject.tsx index f1627b065..d8b444210 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionProject/SubmissionProject.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionProject/SubmissionProject.tsx @@ -9,7 +9,7 @@ import { StyledSubmissionProject } from "./styles"; export function SubmissionProject() { const { t } = useTranslation(); - const { submissionData, setSubmissionData } = useContext(SubmissionFormContext); + const { submissionData, setSubmissionData, allFormDisabled } = useContext(SubmissionFormContext); const [userInput, setUserInput] = useState(""); const { activeVaults } = useVaults(); @@ -36,7 +36,7 @@ export function SubmissionProject() { key={index} vault={vault} expanded={false} - onSelect={() => handleSelectedProject(vault)} + onSelect={!allFormDisabled ? () => handleSelectedProject(vault) : () => {}} selected={submissionData?.project?.projectId === vault.id} /> ); diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionProcessed/SubmissionProcessed.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionProcessed/SubmissionProcessed.tsx index 77d07de68..2e63a8561 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionProcessed/SubmissionProcessed.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionProcessed/SubmissionProcessed.tsx @@ -27,7 +27,7 @@ export function SubmissionProcessed() { const getSubmissionOnServerStatus = () => { let color = Colors.yellow; - let text = t("pending"); + let text = `${t("pending")}...`; switch (submissionStatus.server) { case SubmissionOpStatus.Success: diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx index 347e75d31..9e7c8b863 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx @@ -1,4 +1,6 @@ +import MDEditor from "@uiw/react-md-editor"; import { Alert, Button, FormInput, Loading } from "components"; +import { disallowedElementsMarkdown } from "constants/constants"; import { SubmissionFormContext } from "pages/Submissions/SubmissionFormPage/store"; import { useContext } from "react"; import { useTranslation } from "react-i18next"; @@ -34,15 +36,27 @@ export function SubmissionReview() { />
- {/* + + */} + /> - + {/* */}
+ {submissionData.ref === "audit-wizard" && ( + + )} diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/styles.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/styles.ts index e5e132d48..3779669a5 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/styles.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/styles.ts @@ -11,7 +11,9 @@ export const StyledSubmissionReview = styled.div` } .buttons { + margin-top: ${getSpacing(2)}; display: flex; + gap: ${getSpacing(4)}; justify-content: flex-end; } `; diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index d05495ee9..d08b2d41e 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -1,7 +1,11 @@ -import { Seo } from "components"; +import { IVulnerabilitySeverity } from "@hats-finance/shared"; +import ErrorIcon from "@mui/icons-material/ErrorOutlineOutlined"; +import ClearIcon from "@mui/icons-material/HighlightOffOutlined"; +import { Button, Seo } from "components"; import { LocalStorage } from "constants/constants"; import { LogClaimContract } from "contracts"; import { useVaults } from "hooks/subgraph/vaults/useVaults"; +import useConfirm from "hooks/useConfirm"; import { calcCid } from "pages/Submissions/SubmissionFormPage/encrypt"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -21,15 +25,45 @@ import { StyledSubmissionFormPage } from "./styles"; import { submitVulnerabilitySubmission } from "./submissionsService.api"; import { ISubmissionData, SubmissionOpStatus, SubmissionStep } from "./types"; +const auditWizardExample = JSON.parse(`{ + "project": { + "projectId": "0x18fbe473b99b3d68f5ad35881149ea0e1b56e091" + }, + "signature": "15bcdbe3bf773174702edd02067437d59d8f3f963cebd8661a83baf89cb75bc4d4e55653e7a1f0357f5532e9ea40b4eb78a4cbbe9bc51130505b64976fa1238de8920bc23312a0c5f9f3a772ce29cfd2ad39a9d18572173621fbc99cb7a31ca9538ff468e0ab743ba202667fcd24870e5d0d14eb6a8a0adfb5d23db208e427dd83ab757e4cf0d0dc8da215f18bb2587d94cfa94e40bf7f8e03dee0e02bc5a14bd3829b9d8d25884397b432aef10aa361431d8f59fc5a97e5a129e507509cdf36b1052d7d432c0701c5dfbe92ef532bf6c38a340c98a05b53a8856ff1f3afd97297815a1b82ae0cd2e71166706232a03eb9fc24c1db70ae273632fc658b28ab61", + "contact": { + "beneficiary": "0x56E889664F5961452E5f4183AA13AF568198eaD2", + "communicationChannel": "test@auditware.io", + "communicationChannelType": "email" + }, + "submissionDescriptions": { + "descriptions": [ + { + "title": "Malicious pair can re-enter 'VeryFastRouter' to drain funds", + "description": "VeryFastRouter::swap is the main entry point for a user to perform a batch of sell and buy orders on the new Sudoswap router, allowing partial fill conditions to be specified. Sell orders are executed first, followed by buy orders. The LSSVMPair contracts themselves are implemented in such a way that re-entrancy is not possible, but the same is not true of the VeryFastRouter. Assuming a user calls VeryFastRouter::swap, selling some NFTs and passing in some additional ETH value for subsequent buy orders, an attacker can re-enter this function under certain conditions to steal the original caller's funds. Given that this function does not check whether the user input contains valid pairs, an attacker can use this to manipulate", + "severity": "high severity", + "files": ["base64", "base64"] + }, + { + "title": "Lack of Input Validation in Transfer Function", + "description": "The smart contract being audited exhibits a low severity issue related to the lack of input validation in the transfer function. The contract allows users to transfer tokens between addresses, but it fails to adequately validate the input parameters, which can lead to potential vulnerabilities.", + "severity": "Low", + "files": ["base64"] + } + ] + } +}`); + export const SubmissionFormPage = () => { const { t } = useTranslation(); + const confirm = useConfirm(); const [searchParams] = useSearchParams(); const { chain } = useNetwork(); const [currentStep, setCurrentStep] = useState(); const [submissionData, setSubmissionData] = useState(); + const [allFormDisabled, setAllFormDisabled] = useState(false); - const { activeVaults } = useVaults(); + const { activeVaults, vaultsReadyAllChains } = useVaults(); const vault = (activeVaults ?? []).find((vault) => vault.id === submissionData?.project?.projectId); const steps = useMemo( @@ -81,6 +115,7 @@ export const SubmissionFormPage = () => { callReset(); setSubmissionData(SUBMISSION_INIT_DATA); setCurrentStep(0); + setAllFormDisabled(false); }; // Loads initial state of the vault @@ -175,6 +210,79 @@ export const SubmissionFormPage = () => { sendVulnerabilityOnChain(calculatedCid); }, [sendVulnerabilityOnChain, submissionData]); + const handleClearSubmission = async () => { + const wantsToClear = await confirm({ + title: t("clearSubmission"), + titleIcon: , + description: t("clearSubmissionExplanation"), + cancelText: t("no"), + confirmText: t("clearForm"), + }); + + if (!wantsToClear) return; + reset(); + }; + + const populateDataFromAuditWizard = async (auditWizardSubmission: any) => { + if (!vaultsReadyAllChains) return; + + if (submissionData?.project?.projectId) { + const wantsToClear = await confirm({ + title: t("existingSubmission"), + titleIcon: , + description: t("clearExistingSubmissionAuditWizardExplanation"), + cancelText: t("no"), + confirmText: t("clearForm"), + }); + if (!wantsToClear) return; + } + + reset(); + + const vault = activeVaults && activeVaults.find((vault) => vault.id === auditWizardSubmission.project.projectId); + if (!vault || !vault.description) { + return confirm({ + title: t("projectNotAvailable"), + titleIcon: , + description: t("projectNotAvailableExplanation"), + confirmText: t("gotIt"), + }); + } + + setSubmissionData((prev) => ({ + ...prev!, + ref: "audit-wizard", + project: { + verified: true, + projectName: vault.description?.["project-metadata"].name!, + ...auditWizardSubmission.project, + }, + terms: { verified: false }, + contact: { verified: false, ...auditWizardSubmission.contact }, + submissionsDescriptions: { + verified: false, + submission: "", + submissionMessage: "", + descriptions: auditWizardSubmission.submissionDescriptions.descriptions.map((desc: any) => { + const severity = (vault.description?.severities as IVulnerabilitySeverity[]).find( + (sev) => + desc.severity.toLowerCase()?.includes(sev.name.toLowerCase()) || + sev.name.toLowerCase()?.includes(desc.severity.toLowerCase()) + ); + return { + title: desc.title, + description: desc.description, + severity: severity?.name.toLowerCase() ?? desc.severity.toLowerCase(), + isEncrypted: !severity?.decryptSubmissions, + files: [], + }; + }), + }, + submissionResult: undefined, + })); + setAllFormDisabled(true); + }; + const context: ISubmissionFormContext = { reset, vault, @@ -186,12 +294,37 @@ export const SubmissionFormPage = () => { sendSubmissionToServer, isSubmitting, isSigningSubmission, + allFormDisabled, }; return ( <> + +
+ {submissionData?.ref === "audit-wizard" && ( +
+ audit wizard logo +

{t("Submissions.submissionSubmittedViaAuditWizard")}

+
+ )} + {submissionData?.project?.projectId && ( + + )} +
+
{steps.map((step, index) => ( diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/store.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/store.ts index 9b9e63e56..b261a02d0 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/store.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/store.ts @@ -16,6 +16,7 @@ export interface ISubmissionFormContext { submitSubmission: Function; sendSubmissionToServer: Function; reset: Function; + allFormDisabled: boolean; } export const SubmissionFormContext = createContext(undefined as any); diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/styles.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/styles.ts index ab3024338..b478f0dbc 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/styles.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/styles.ts @@ -1,4 +1,5 @@ import styled from "styled-components"; +import { getSpacing } from "styles"; export const StyledSubmissionFormPage = styled.div` position: relative; @@ -7,4 +8,30 @@ export const StyledSubmissionFormPage = styled.div` max-width: var(--element-max-width); margin: auto; } + + .top-controls { + display: flex; + align-items: center; + gap: ${getSpacing(1)}; + margin-bottom: ${getSpacing(4)}; + + .auditWizardSubmission { + display: flex; + flex-direction: column; + gap: ${getSpacing(1)}; + align-items: flex-start; + background: var(--background-3); + width: fit-content; + padding: ${getSpacing(1.5)} ${getSpacing(2)}; + border-radius: ${getSpacing(1)}; + + img { + height: ${getSpacing(3)}; + } + + p { + font-size: var(--xxsmall); + } + } + } `; diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts index 898be8411..1a7b22d4b 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts @@ -30,11 +30,11 @@ export async function submitVulnerabilitySubmission( createIssueRequests: vault.description?.["project-metadata"].type === "audit" ? submissionData.submissionsDescriptions.descriptions - .filter((desc) => !desc.isEncrypted) - .map((description) => ({ + ?.filter((desc) => !desc.isEncrypted) + ?.map((description) => ({ issueTitle: description.title, issueDescription: getGithubIssueDescription(submissionData, description), - issueFiles: description.files.map((file) => file.ipfsHash), + issueFiles: description.files?.map((file) => file.ipfsHash), })) : [], }; diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts index 28c70bcd1..a438a4dcb 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts @@ -57,6 +57,7 @@ export interface ISubmissionData { submissionsDescriptions: ISubmissionsDescriptionsData; terms?: ISubmissionTermsData; submissionResult?: ISubmissionResultData; + ref?: "audit-wizard"; } export enum SubmissionOpStatus { From 7a381b762f7d8a4d8cdae4669cb6bc6cec28ff45 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 11 Sep 2023 15:11:42 +0100 Subject: [PATCH 2/9] test --- .../SubmissionFormPage/SubmissionFormPage.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index d08b2d41e..950d24784 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -223,6 +223,18 @@ export const SubmissionFormPage = () => { reset(); }; + window.addEventListener("message", function (event) { + // Check the origin of the sender + // if (event.origin === 'http://localhost:3000') { + // Process the received data + console.log("Received message:", event.data); + populateDataFromAuditWizard(event.data); + // } else { + // // Ignore messages from untrusted origins + // console.warn('Received message from untrusted origin:', event.origin); + // } + }); + const populateDataFromAuditWizard = async (auditWizardSubmission: any) => { if (!vaultsReadyAllChains) return; From 1cc1359c66af11c5497280566bbf1a6f6a711873 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 11 Sep 2023 15:41:39 +0100 Subject: [PATCH 3/9] changes --- .../SubmissionFormPage/SubmissionFormPage.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index 950d24784..62f295ea0 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -62,6 +62,7 @@ export const SubmissionFormPage = () => { const [currentStep, setCurrentStep] = useState(); const [submissionData, setSubmissionData] = useState(); const [allFormDisabled, setAllFormDisabled] = useState(false); + const [receivedDataFromAuditWizard, setReceivedDataFromAuditWizard] = useState(); const { activeVaults, vaultsReadyAllChains } = useVaults(); const vault = (activeVaults ?? []).find((vault) => vault.id === submissionData?.project?.projectId); @@ -227,12 +228,10 @@ export const SubmissionFormPage = () => { // Check the origin of the sender // if (event.origin === 'http://localhost:3000') { // Process the received data - console.log("Received message:", event.data); - populateDataFromAuditWizard(event.data); - // } else { - // // Ignore messages from untrusted origins - // console.warn('Received message from untrusted origin:', event.origin); - // } + if (receivedDataFromAuditWizard) return; + if (!event.data.signature) return; + console.log("Received message:", event); + setReceivedDataFromAuditWizard(event.data); }); const populateDataFromAuditWizard = async (auditWizardSubmission: any) => { @@ -295,6 +294,14 @@ export const SubmissionFormPage = () => { setAllFormDisabled(true); }; + useEffect(() => { + if (!vaultsReadyAllChains) return; + if (!receivedDataFromAuditWizard) return; + + populateDataFromAuditWizard(receivedDataFromAuditWizard); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vaultsReadyAllChains, receivedDataFromAuditWizard]); + const context: ISubmissionFormContext = { reset, vault, From b514cd5cf32d0ee0fafcd08572ac7956470f17cb Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 11 Sep 2023 18:35:48 +0100 Subject: [PATCH 4/9] finished audit wizard integration --- packages/web/src/constants/constants.ts | 2 + packages/web/src/languages/en.json | 4 + .../SubmissionContactInfo.tsx | 2 +- .../SubmissionReview/SubmissionReview.tsx | 4 +- .../SubmissionFormPage/SubmissionFormPage.tsx | 132 +++++++++++------- .../submissionsService.api.ts | 15 +- .../Submissions/SubmissionFormPage/types.ts | 49 ++++++- 7 files changed, 149 insertions(+), 59 deletions(-) diff --git a/packages/web/src/constants/constants.ts b/packages/web/src/constants/constants.ts index 4a21f267b..43363dcf6 100644 --- a/packages/web/src/constants/constants.ts +++ b/packages/web/src/constants/constants.ts @@ -26,6 +26,8 @@ export const MAX_NFT_TIER = 3; export const stagingServiceUrl = "https://hats-backend-dev.herokuapp.com/v1"; export const prodServiceUrl = "https://hats-backend-prod.herokuapp.com/v1"; +export const auditWizardVerifyService = "https://app.auditwizard.io:5000/submissions/finalizeHats"; + export const NFTContractDataProxy = { ["0xCCaadc293FaAEa229e0ca4A22B0330b65634b483".toLowerCase()]: "0x1d25bf3d0f8997282055a1a242fa2b146e7b4ec5", ["0x571f39d351513146248AcafA9D0509319A327C4D".toLowerCase()]: "0xe127be2bc276142039bc16251bb04e15b2b34f25", diff --git a/packages/web/src/languages/en.json b/packages/web/src/languages/en.json index 6cce55e4d..268eef84f 100644 --- a/packages/web/src/languages/en.json +++ b/packages/web/src/languages/en.json @@ -590,6 +590,10 @@ "projectNotAvailable": "Project not available", "projectNotAvailableExplanation": "The project on which you are attempting to submit a vulnerability is no longer available. \n\n If you think this is an error, please contact Hats support.", "understand": "Understand", + "submissionChanged": "Submission changed", + "submissionChangedExplanationAuditWizard": "The submission you are trying to edit has changed. \n\n If you want to edit the submission, please go back to Audit Wizard.", + "submissionNotValid": "Submission not valid", + "submissionNotValidExplanationAuditWizard": "The submission you are trying to edit is not valid. \n\n Please go back to Audit Wizard and try again.", "PGPTool": { "title": "PGP tool", "unlockPgpTool": "Unlock the PGP tool", diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx index efa33353e..e37324085 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionContactInfo/SubmissionContactInfo.tsx @@ -44,7 +44,7 @@ export function SubmissionContactInfo() { setSubmissionData((prev) => { if (prev) return { - ...prev!, + ...prev, contact: { ...contactData, verified: true }, submissionsDescriptions: { ...prev.submissionsDescriptions, verified: false }, submissionResult: undefined, diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx index 9e7c8b863..05a6ac446 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionSubmit/components/SubmissionReview/SubmissionReview.tsx @@ -47,7 +47,7 @@ export function SubmissionReview() { {/* */}
- {submissionData.ref === "audit-wizard" && ( + {/* {submissionData.ref === "audit-wizard" && ( - )} + )} */} diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index 62f295ea0..ab3317998 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -10,6 +10,7 @@ import { calcCid } from "pages/Submissions/SubmissionFormPage/encrypt"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { useSearchParams } from "react-router-dom"; +import { IS_PROD } from "settings"; import { getAppVersion } from "utils"; import { useNetwork, useWaitForTransaction } from "wagmi"; import { @@ -22,36 +23,40 @@ import { import SubmissionFormCard from "../SubmissionFormPage/SubmissionFormCard/SubmissionFormCard"; import { ISubmissionFormContext, SUBMISSION_INIT_DATA, SubmissionFormContext } from "./store"; import { StyledSubmissionFormPage } from "./styles"; -import { submitVulnerabilitySubmission } from "./submissionsService.api"; -import { ISubmissionData, SubmissionOpStatus, SubmissionStep } from "./types"; - -const auditWizardExample = JSON.parse(`{ - "project": { - "projectId": "0x18fbe473b99b3d68f5ad35881149ea0e1b56e091" - }, - "signature": "15bcdbe3bf773174702edd02067437d59d8f3f963cebd8661a83baf89cb75bc4d4e55653e7a1f0357f5532e9ea40b4eb78a4cbbe9bc51130505b64976fa1238de8920bc23312a0c5f9f3a772ce29cfd2ad39a9d18572173621fbc99cb7a31ca9538ff468e0ab743ba202667fcd24870e5d0d14eb6a8a0adfb5d23db208e427dd83ab757e4cf0d0dc8da215f18bb2587d94cfa94e40bf7f8e03dee0e02bc5a14bd3829b9d8d25884397b432aef10aa361431d8f59fc5a97e5a129e507509cdf36b1052d7d432c0701c5dfbe92ef532bf6c38a340c98a05b53a8856ff1f3afd97297815a1b82ae0cd2e71166706232a03eb9fc24c1db70ae273632fc658b28ab61", - "contact": { - "beneficiary": "0x56E889664F5961452E5f4183AA13AF568198eaD2", - "communicationChannel": "test@auditware.io", - "communicationChannelType": "email" - }, - "submissionDescriptions": { - "descriptions": [ - { - "title": "Malicious pair can re-enter 'VeryFastRouter' to drain funds", - "description": "VeryFastRouter::swap is the main entry point for a user to perform a batch of sell and buy orders on the new Sudoswap router, allowing partial fill conditions to be specified. Sell orders are executed first, followed by buy orders. The LSSVMPair contracts themselves are implemented in such a way that re-entrancy is not possible, but the same is not true of the VeryFastRouter. Assuming a user calls VeryFastRouter::swap, selling some NFTs and passing in some additional ETH value for subsequent buy orders, an attacker can re-enter this function under certain conditions to steal the original caller's funds. Given that this function does not check whether the user input contains valid pairs, an attacker can use this to manipulate", - "severity": "high severity", - "files": ["base64", "base64"] - }, - { - "title": "Lack of Input Validation in Transfer Function", - "description": "The smart contract being audited exhibits a low severity issue related to the lack of input validation in the transfer function. The contract allows users to transfer tokens between addresses, but it fails to adequately validate the input parameters, which can lead to potential vulnerabilities.", - "severity": "Low", - "files": ["base64"] - } - ] - } -}`); +import { submitVulnerabilitySubmission, verifyAuditWizardSignature } from "./submissionsService.api"; +import { + IAuditWizardSubmissionData, + ISubmissionData, + SubmissionOpStatus, + SubmissionStep, + getCurrentAuditwizardSubmission, +} from "./types"; + +// const auditWizardExample = JSON.parse(`{ +// "signature": "47732adf56d4ff7e4b0d0d6d8f09217044a0b8c9d22c06fd2713f7ffc27d210816dcfd35ef3e51a54a4be82027e88bfbd2dd58c36364d51002668e21fe8a4fe2b05baa673fc7152903166b5ac19b5641772327b7567f169888f7214d0a42f219652c17c5da70cf2c1a02319b139875a1aac9405ef9f2fb9058c89e00381cfabf154751853a0e406086ad0faa82b2bd8b03ec0e4b844c954eef3e9226772258bc5de5d7b2d0b4f731dc3763b9632288595ae3b2e505fb8f4e69969f82d1c6988de485dffdb2de553918c97eb7adf50a1e2680880dce59706869eec758f12c457a1d57a24032d02e7ec027584e63ffa5921cffea10bf26d32a3ab3cfea45216488", +// "project": { +// "projectId": "0x18fbe473b99b3d68f5ad35881149ea0e1b56e091" +// }, +// "contact": { +// "beneficiary": "0x6085fBB553F125C0234b28dE7D4228F2873B3428", +// "communicationChannel": "test@auditware.io", +// "communicationChannelType": "email" +// }, +// "submissionDescriptions": { +// "descriptions": [ +// { +// "title": "Malicious pair can re-enter 'VeryFastRouter' to drain funds", +// "description": "VeryFastRouter::swap is the main entry point for a user to perform a batch of sell and buy orders on the new Sudoswap router, allowing partial fill conditions to be specified. Sell orders are executed first, followed by buy orders. The LSSVMPair contracts themselves are implemented in such a way that re-entrancy is not possible, but the same is not true of the VeryFastRouter. Assuming a user calls VeryFastRouter::swap, selling some NFTs and passing in some additional ETH value for subsequent buy orders, an attacker can re-enter this function under certain conditions to steal the original caller's funds. Given that this function does not check whether the user input contains valid pairs, an attacker can use this to manipulate", +// "severity": "Critical" +// }, +// { +// "title": "Lack of Input Validation in Transfer Function", +// "description": "The smart contract being audited exhibits a low severity issue related to the lack of input validation in the transfer function. The contract allows users to transfer tokens between addresses, but it fails to adequately validate the input parameters, which can lead to potential vulnerabilities.", +// "severity": "Low" +// } +// ] +// } +// }`); export const SubmissionFormPage = () => { const { t } = useTranslation(); @@ -62,7 +67,7 @@ export const SubmissionFormPage = () => { const [currentStep, setCurrentStep] = useState(); const [submissionData, setSubmissionData] = useState(); const [allFormDisabled, setAllFormDisabled] = useState(false); - const [receivedDataFromAuditWizard, setReceivedDataFromAuditWizard] = useState(); + const [receivedSubmissionAuditwizard, setReceivedSubmissionAuditwizard] = useState(); const { activeVaults, vaultsReadyAllChains } = useVaults(); const vault = (activeVaults ?? []).find((vault) => vault.id === submissionData?.project?.projectId); @@ -147,6 +152,11 @@ export const SubmissionFormPage = () => { } else if (cachedData.version !== getAppVersion()) { setSubmissionData(SUBMISSION_INIT_DATA); } else { + if (cachedData.ref === "audit-wizard") { + setAllFormDisabled(true); + setReceivedSubmissionAuditwizard(cachedData.auditWizardData); + } + setSubmissionData(cachedData); } } catch (e) { @@ -208,8 +218,33 @@ export const SubmissionFormPage = () => { const submission = submissionData?.submissionsDescriptions?.submission; const calculatedCid = await calcCid(submission); + if (submissionData.ref === "audit-wizard") { + if (!receivedSubmissionAuditwizard) return; + // Verify if the submission was not changed and validate the signature + const auditwizardSubmission = getCurrentAuditwizardSubmission(receivedSubmissionAuditwizard, submissionData); + + if (JSON.stringify(receivedSubmissionAuditwizard) !== JSON.stringify(auditwizardSubmission)) { + return confirm({ + title: t("submissionChanged"), + titleIcon: , + description: t("submissionChangedExplanationAuditWizard"), + confirmText: t("gotIt"), + }); + } + + const res = await verifyAuditWizardSignature(auditwizardSubmission); + if (!res) { + return confirm({ + title: t("submissionNotValid"), + titleIcon: , + description: t("submissionNotValidExplanationAuditWizard"), + confirmText: t("gotIt"), + }); + } + } + sendVulnerabilityOnChain(calculatedCid); - }, [sendVulnerabilityOnChain, submissionData]); + }, [sendVulnerabilityOnChain, submissionData, receivedSubmissionAuditwizard, confirm, t]); const handleClearSubmission = async () => { const wantsToClear = await confirm({ @@ -225,16 +260,14 @@ export const SubmissionFormPage = () => { }; window.addEventListener("message", function (event) { - // Check the origin of the sender - // if (event.origin === 'http://localhost:3000') { - // Process the received data - if (receivedDataFromAuditWizard) return; - if (!event.data.signature) return; - console.log("Received message:", event); - setReceivedDataFromAuditWizard(event.data); + if (IS_PROD && !event.origin.includes("auditwizard.io")) return; + + if (receivedSubmissionAuditwizard) return; + if (!event.data.signature || !event.data.project || !event.data.contact) return; + setReceivedSubmissionAuditwizard(event.data); }); - const populateDataFromAuditWizard = async (auditWizardSubmission: any) => { + const populateDataFromAuditWizard = async (auditWizardSubmission: IAuditWizardSubmissionData) => { if (!vaultsReadyAllChains) return; if (submissionData?.project?.projectId) { @@ -263,6 +296,7 @@ export const SubmissionFormPage = () => { setSubmissionData((prev) => ({ ...prev!, ref: "audit-wizard", + auditWizardData: auditWizardSubmission, project: { verified: true, projectName: vault.description?.["project-metadata"].name!, @@ -274,7 +308,7 @@ export const SubmissionFormPage = () => { verified: false, submission: "", submissionMessage: "", - descriptions: auditWizardSubmission.submissionDescriptions.descriptions.map((desc: any) => { + descriptions: auditWizardSubmission.submissionsDescriptions.descriptions.map((desc: any) => { const severity = (vault.description?.severities as IVulnerabilitySeverity[]).find( (sev) => desc.severity.toLowerCase()?.includes(sev.name.toLowerCase()) || @@ -294,13 +328,14 @@ export const SubmissionFormPage = () => { setAllFormDisabled(true); }; + // Populate data from audit wizard once vaults are ready useEffect(() => { if (!vaultsReadyAllChains) return; - if (!receivedDataFromAuditWizard) return; + if (!receivedSubmissionAuditwizard) return; - populateDataFromAuditWizard(receivedDataFromAuditWizard); + populateDataFromAuditWizard(receivedSubmissionAuditwizard); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [vaultsReadyAllChains, receivedDataFromAuditWizard]); + }, [vaultsReadyAllChains, receivedSubmissionAuditwizard]); const context: ISubmissionFormContext = { reset, @@ -318,15 +353,6 @@ export const SubmissionFormPage = () => { return ( <> -
diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts index 1a7b22d4b..87579c9d3 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts @@ -1,8 +1,9 @@ import { IVault } from "@hats-finance/shared"; import { axiosClient } from "config/axiosClient"; +import { auditWizardVerifyService } from "constants/constants"; import { BASE_SERVICE_URL } from "settings"; import { getGithubIssueDescription } from "../SubmissionFormPage/FormSteps/SubmissionDescriptions/utils"; -import { ISubmissionData, ISubmitSubmissionRequest } from "./types"; +import { IAuditWizardSubmissionData, ISubmissionData, ISubmitSubmissionRequest } from "./types"; /** * Submits a new vulnerability submission @@ -46,3 +47,15 @@ export async function submitVulnerabilitySubmission( return { success: false }; } } + +/** + * Verifies the signature sent by Audit Wizard + */ +export async function verifyAuditWizardSignature(auditWizardSubmission: IAuditWizardSubmissionData): Promise { + try { + const res = await axiosClient.put(`${auditWizardVerifyService}`, auditWizardSubmission); + return res.status === 200; + } catch (error) { + return false; + } +} diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts b/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts index a438a4dcb..05a0855b2 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/types.ts @@ -32,7 +32,7 @@ export interface ISubmissionsDescriptionsData { description: string; severity: string; files: ISavedFile[]; - sessionKey: SessionKey; + sessionKey?: SessionKey; isEncrypted?: boolean; }[]; } @@ -51,13 +51,14 @@ export interface ISubmissionResultData { } export interface ISubmissionData { - version: string; + version?: string; project?: ISubmissionProjectData; contact?: ISubmissionContactData; submissionsDescriptions: ISubmissionsDescriptionsData; terms?: ISubmissionTermsData; submissionResult?: ISubmissionResultData; ref?: "audit-wizard"; + auditWizardData?: IAuditWizardSubmissionData; } export enum SubmissionOpStatus { @@ -80,3 +81,47 @@ export interface ISubmitSubmissionRequest { issueFiles: string[]; }[]; } + +export interface IAuditWizardSubmissionData { + signature: string; + contact: { + beneficiary: string; + communicationChannel: string; + communicationChannelType: ISubmissionContactData["communicationChannelType"]; + }; + project: { projectId: string }; + submissionsDescriptions: { descriptions: { title: string; severity: string; description: string }[] }; +} + +/** + * This functions puts the current state of the form into the AuditWizard format in order to + * verify it with their API. The from should have exactly the same values as the received from + * audit wizard. + */ +export const getCurrentAuditwizardSubmission = ( + awSubmission: IAuditWizardSubmissionData, + form: ISubmissionData +): IAuditWizardSubmissionData => { + return { + ...awSubmission, + contact: { + ...awSubmission.contact, + beneficiary: form.contact?.beneficiary ?? "", + communicationChannel: form.contact?.communicationChannel ?? "", + communicationChannelType: form.contact?.communicationChannelType ?? "email", + }, + project: { + ...awSubmission.project, + projectId: form.project?.projectId ?? "", + }, + submissionsDescriptions: { + ...awSubmission.submissionsDescriptions, + descriptions: + form.submissionsDescriptions?.descriptions.map((d, idx) => ({ + title: d.title, + description: d.description, + severity: awSubmission.submissionsDescriptions.descriptions[idx].severity, + })) ?? [], + }, + }; +}; From 14370c094693740f8b34ce880d23b0ba4351fc38 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 11 Sep 2023 19:23:59 +0100 Subject: [PATCH 5/9] fixes --- .../SubmissionFormPage/SubmissionFormPage.tsx | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index ab3317998..6f868df20 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -152,11 +152,7 @@ export const SubmissionFormPage = () => { } else if (cachedData.version !== getAppVersion()) { setSubmissionData(SUBMISSION_INIT_DATA); } else { - if (cachedData.ref === "audit-wizard") { - setAllFormDisabled(true); - setReceivedSubmissionAuditwizard(cachedData.auditWizardData); - } - + if (cachedData.ref === "audit-wizard") setAllFormDisabled(true); setSubmissionData(cachedData); } } catch (e) { @@ -219,11 +215,11 @@ export const SubmissionFormPage = () => { const calculatedCid = await calcCid(submission); if (submissionData.ref === "audit-wizard") { - if (!receivedSubmissionAuditwizard) return; + if (!submissionData.auditWizardData) return; // Verify if the submission was not changed and validate the signature - const auditwizardSubmission = getCurrentAuditwizardSubmission(receivedSubmissionAuditwizard, submissionData); + const auditwizardSubmission = getCurrentAuditwizardSubmission(submissionData.auditWizardData, submissionData); - if (JSON.stringify(receivedSubmissionAuditwizard) !== JSON.stringify(auditwizardSubmission)) { + if (JSON.stringify(submissionData.auditWizardData) !== JSON.stringify(auditwizardSubmission)) { return confirm({ title: t("submissionChanged"), titleIcon: , @@ -244,7 +240,7 @@ export const SubmissionFormPage = () => { } sendVulnerabilityOnChain(calculatedCid); - }, [sendVulnerabilityOnChain, submissionData, receivedSubmissionAuditwizard, confirm, t]); + }, [sendVulnerabilityOnChain, submissionData, confirm, t]); const handleClearSubmission = async () => { const wantsToClear = await confirm({ @@ -259,14 +255,6 @@ export const SubmissionFormPage = () => { reset(); }; - window.addEventListener("message", function (event) { - if (IS_PROD && !event.origin.includes("auditwizard.io")) return; - - if (receivedSubmissionAuditwizard) return; - if (!event.data.signature || !event.data.project || !event.data.contact) return; - setReceivedSubmissionAuditwizard(event.data); - }); - const populateDataFromAuditWizard = async (auditWizardSubmission: IAuditWizardSubmissionData) => { if (!vaultsReadyAllChains) return; @@ -328,6 +316,20 @@ export const SubmissionFormPage = () => { setAllFormDisabled(true); }; + useEffect(() => { + const checkEvent = (event: MessageEvent) => { + if (IS_PROD && !event.origin.includes("auditwizard.io")) return; + if (!event.data.signature || !event.data.project || !event.data.contact) return; + setReceivedSubmissionAuditwizard(event.data); + }; + + window.addEventListener("message", checkEvent); + + return () => { + window.removeEventListener("message", checkEvent); + }; + }, []); + // Populate data from audit wizard once vaults are ready useEffect(() => { if (!vaultsReadyAllChains) return; From 949c54d49b77a5654db0045cdd5f293b2f544086 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Fri, 15 Sep 2023 08:56:22 -0700 Subject: [PATCH 6/9] Removed commented code --- .../SubmissionFormPage/SubmissionFormPage.tsx | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index 6f868df20..bf9a4d7e6 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -32,32 +32,6 @@ import { getCurrentAuditwizardSubmission, } from "./types"; -// const auditWizardExample = JSON.parse(`{ -// "signature": "47732adf56d4ff7e4b0d0d6d8f09217044a0b8c9d22c06fd2713f7ffc27d210816dcfd35ef3e51a54a4be82027e88bfbd2dd58c36364d51002668e21fe8a4fe2b05baa673fc7152903166b5ac19b5641772327b7567f169888f7214d0a42f219652c17c5da70cf2c1a02319b139875a1aac9405ef9f2fb9058c89e00381cfabf154751853a0e406086ad0faa82b2bd8b03ec0e4b844c954eef3e9226772258bc5de5d7b2d0b4f731dc3763b9632288595ae3b2e505fb8f4e69969f82d1c6988de485dffdb2de553918c97eb7adf50a1e2680880dce59706869eec758f12c457a1d57a24032d02e7ec027584e63ffa5921cffea10bf26d32a3ab3cfea45216488", -// "project": { -// "projectId": "0x18fbe473b99b3d68f5ad35881149ea0e1b56e091" -// }, -// "contact": { -// "beneficiary": "0x6085fBB553F125C0234b28dE7D4228F2873B3428", -// "communicationChannel": "test@auditware.io", -// "communicationChannelType": "email" -// }, -// "submissionDescriptions": { -// "descriptions": [ -// { -// "title": "Malicious pair can re-enter 'VeryFastRouter' to drain funds", -// "description": "VeryFastRouter::swap is the main entry point for a user to perform a batch of sell and buy orders on the new Sudoswap router, allowing partial fill conditions to be specified. Sell orders are executed first, followed by buy orders. The LSSVMPair contracts themselves are implemented in such a way that re-entrancy is not possible, but the same is not true of the VeryFastRouter. Assuming a user calls VeryFastRouter::swap, selling some NFTs and passing in some additional ETH value for subsequent buy orders, an attacker can re-enter this function under certain conditions to steal the original caller's funds. Given that this function does not check whether the user input contains valid pairs, an attacker can use this to manipulate", -// "severity": "Critical" -// }, -// { -// "title": "Lack of Input Validation in Transfer Function", -// "description": "The smart contract being audited exhibits a low severity issue related to the lack of input validation in the transfer function. The contract allows users to transfer tokens between addresses, but it fails to adequately validate the input parameters, which can lead to potential vulnerabilities.", -// "severity": "Low" -// } -// ] -// } -// }`); - export const SubmissionFormPage = () => { const { t } = useTranslation(); const confirm = useConfirm(); From c0129b02b70f25b63ece62b0176e421cc76dcb88 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 18 Sep 2023 08:51:49 -0700 Subject: [PATCH 7/9] improved auditwzard origin validation --- .../pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index 6f868df20..3c76d1b03 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -318,7 +318,7 @@ export const SubmissionFormPage = () => { useEffect(() => { const checkEvent = (event: MessageEvent) => { - if (IS_PROD && !event.origin.includes("auditwizard.io")) return; + if (IS_PROD && event.origin !== "https://www.auditwizard.io") return; if (!event.data.signature || !event.data.project || !event.data.contact) return; setReceivedSubmissionAuditwizard(event.data); }; From 20419cf7da58e98e8a3facc82b483a9c316a8b54 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 18 Sep 2023 13:12:23 -0700 Subject: [PATCH 8/9] URL verification fix --- .../Submissions/SubmissionFormPage/SubmissionFormPage.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index c75656c36..941cded64 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -292,8 +292,10 @@ export const SubmissionFormPage = () => { useEffect(() => { const checkEvent = (event: MessageEvent) => { - if (IS_PROD && event.origin !== "https://www.auditwizard.io") return; + const host = new URL(event.origin).host; + if (IS_PROD && !host.includes("auditwizard.io")) return; if (!event.data.signature || !event.data.project || !event.data.contact) return; + setReceivedSubmissionAuditwizard(event.data); }; From 1106905339e473bced4ab66a497742980f519ed3 Mon Sep 17 00:00:00 2001 From: Carlos Fontes Date: Mon, 18 Sep 2023 13:21:33 -0700 Subject: [PATCH 9/9] final fix for host verification --- .../pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx index 941cded64..4ea212768 100644 --- a/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx +++ b/packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx @@ -293,7 +293,7 @@ export const SubmissionFormPage = () => { useEffect(() => { const checkEvent = (event: MessageEvent) => { const host = new URL(event.origin).host; - if (IS_PROD && !host.includes("auditwizard.io")) return; + if (IS_PROD && host !== "app.auditwizard.io") return; if (!event.data.signature || !event.data.project || !event.data.contact) return; setReceivedSubmissionAuditwizard(event.data);