diff --git a/SECURITY_DEBT.md b/SECURITY_DEBT.md index a23db08..bb362b3 100644 --- a/SECURITY_DEBT.md +++ b/SECURITY_DEBT.md @@ -1,18 +1,20 @@ # Known Security Debt -## 🔴 Pending — Requires Developer Fix +## 🟢 Fixed ### 1. Regex Injection / ReDoS in Company Search - **File:** `app/api/company/route.js:120` - **Risk:** `companyName` is received unsanitized from a query parameter and concatenated into a `RegExp`. This allows for ReDoS (server hang) and exact match bypass. - **Suggested Fix:** Escape special regex characters before building the `RegExp`, or use an exact Mongo filter instead of `$regex`. - **Detected by:** `eslint-plugin-security` (`detect-non-literal-regexp`), does not block CI (severity: warning). +- **Fix Applied:** Changed the previous regex to a Mongo filter and this way prevent Regex Injection and ReDoS ### 2. List Elements Without `key` (5 instances) - **Files:** `app/settings/manage-contracts/AddContract.tsx:144`, `EditContract.tsx:156`, `components/ContractTable.jsx:99`, `components/datatable.tsx:363`, `components/datatableSeller1.tsx:275` - **Risk:** Not a security issue — it is a React bug that can cause incorrect rendering when reordering/updating lists. - **Suggested Fix:** Add `key={unique-id}` to each iterated element. - **Note:** Temporarily downgraded to a warning via `eslint-disable-next-line` to avoid blocking the pipeline — see comments in each file. +- **Fix Applied:** Added a unique id key to each of the iterated element ## 🟢 Reviewed — False Positive, No Action Required diff --git a/app/api/company/route.js b/app/api/company/route.js index a405ca7..d2d7f96 100644 --- a/app/api/company/route.js +++ b/app/api/company/route.js @@ -116,10 +116,11 @@ export async function GET(req) { if (companyName) { try { await connectMongoDB() - // SECURITY DEBT: ver SECURITY_DEBT.md #1 — companyName no saneado antes de construir el RegExp (ReDoS + regex injection) + const company = await Company.findOne({ - companyName: { $regex: new RegExp("^" + companyName + "$", "i") }, - }).select() + companyName: companyName }, + {}, + { collation: {locale: 'en', strength: 2}}).select() return NextResponse.json({ company }) } catch (error) { diff --git a/app/settings/manage-contracts/AddContract.tsx b/app/settings/manage-contracts/AddContract.tsx index f62ea9c..7f3513e 100644 --- a/app/settings/manage-contracts/AddContract.tsx +++ b/app/settings/manage-contracts/AddContract.tsx @@ -141,8 +141,8 @@ export default function AddContract(props) { offerCompany.map( (singleCompany, index) => !activeCompany.includes(singleCompany.companyName) && ( - // eslint-disable-next-line react/jsx-key -- deuda conocida, ver SECURITY_DEBT.md #2, pendiente de fix diff --git a/app/settings/manage-contracts/EditContract.tsx b/app/settings/manage-contracts/EditContract.tsx index 56cf6eb..d46afb7 100644 --- a/app/settings/manage-contracts/EditContract.tsx +++ b/app/settings/manage-contracts/EditContract.tsx @@ -153,8 +153,8 @@ export default function EditContract(props) { offerCompany.map( (singleCompany, index) => !activeCompany.includes(singleCompany.companyName) && ( - // eslint-disable-next-line react/jsx-key -- deuda conocida, ver SECURITY_DEBT.md #2, pendiente de fix { {singleUser.contracts.map((contract, index) => ( - // eslint-disable-next-line react/jsx-key -- deuda conocida, ver SECURITY_DEBT.md #2, pendiente de fix -
+
{contract.companyName} | {contract.rate}% diff --git a/components/datatable.tsx b/components/datatable.tsx index 994365a..480304e 100644 --- a/components/datatable.tsx +++ b/components/datatable.tsx @@ -360,8 +360,7 @@ export default function DataTable(props) { All {Allcompanies.map((company) => ( - // eslint-disable-next-line react/jsx-key -- deuda conocida, ver SECURITY_DEBT.md #2, pendiente de fix - + {company.companyName} diff --git a/components/datatableSeller1.tsx b/components/datatableSeller1.tsx index 8401115..d6c5d0f 100644 --- a/components/datatableSeller1.tsx +++ b/components/datatableSeller1.tsx @@ -272,8 +272,7 @@ export default function DataTableSeller1(props) { All {Allcompanies.map((company) => ( - // eslint-disable-next-line react/jsx-key -- deuda conocida, ver SECURITY_DEBT.md #2, pendiente de fix - + {company.companyName} ))}