Skip to content

ci(security): integrate Bright CI pipeline for security tests and remediation#817

Open
bright-security-golf[bot] wants to merge 16 commits intostablefrom
bright/865d55fa-c8b6-4d8f-a46f-fa7da5062660
Open

ci(security): integrate Bright CI pipeline for security tests and remediation#817
bright-security-golf[bot] wants to merge 16 commits intostablefrom
bright/865d55fa-c8b6-4d8f-a46f-fa7da5062660

Conversation

@bright-security-golf
Copy link

@bright-security-golf bright-security-golf bot commented Jan 14, 2026

Note

Fixed 15 of 19 vulnerabilities.
Please review the fixes before merging.

Fix Vulnerability Endpoint Affected Files Resolution
[Critical] XPATH Injection GET /api/partners/searchPartners src/partners/partners.service.ts Enhanced XPath validation to prevent injection by adding checks for arithmetic operators and empty brackets.
[Critical] XPATH Injection GET /api/partners/partnerLogin src/partners/partners.service.ts Sanitize and validate XPath expressions to prevent injection attacks.
[Critical] Server Side Template Injection POST /api/render src/app.controller.ts Sanitize user input by removing template expressions before rendering to prevent Server Side Template Injection.
[High] Server Side Request Forgery GET /api/file/google src/file/file.controller.ts, src/file/cloud.providers.metadata.ts Added validation to ensure the 'path' parameter starts with the expected base URL for each cloud provider, preventing unauthorized access to internal resources.
[High] [BL] ID Enumeration GET /api/users/id/1 src/users/users.controller.ts Added authorization check to ensure users can only access their own information by verifying the requester's identity against the requested user ID.
[High] Server Side Request Forgery GET /api/file src/file/file.service.ts Added hostname validation to restrict SSRF by allowing only specific hosts.
[High] Local File Inclusion GET /api/file src/file/file.service.ts Implemented path validation to restrict file access to predefined directories, preventing unauthorized file inclusion.
[High] Server Side Request Forgery GET /api/file/digital_ocean src/file/file.service.ts Added hostname validation to restrict server-side requests to a whitelist of allowed hosts, preventing SSRF attacks.
[High] Server Side Request Forgery GET /api/file/aws src/file/file.controller.ts Added validation to ensure the 'path' parameter starts with the expected base URL for AWS requests.
[High] Server Side Request Forgery GET /api/file/azure src/file/file.controller.ts Added validation to ensure the 'path' parameter starts with the expected base URL for Azure requests.
[Medium] Secret Tokens Leak GET /api/secrets src/app.controller.ts Replaced hardcoded secret tokens with environment variables to prevent leaks.
[Medium] GraphQL Introspection POST /graphql src/app.module.ts Disabled GraphQL introspection in the server configuration to prevent schema exposure.
[Medium] Database Error Message Disclosure POST /graphql src/testimonials/testimonials.service.ts Replace detailed error messages with a generic error message to prevent information leakage.
[Medium] Full Path Disclosure DELETE /api/file src/file/file.service.ts Wrap file deletion in a try-catch block and throw a generic error message to prevent full path disclosure.
[Medium] Full Path Disclosure GET /api/file src/file/file.controller.ts Added generic error handling to prevent full path disclosure in error messages.
[Medium] [BL] Business Constraint Bypass GET /api/products/latest src/products/products.service.ts Attempted fix: Enforced a maximum limit on the number of products returned to prevent business constraint bypass.
[Medium] Secret Tokens Leak GET /api/config src/app.service.ts Attempted fix: Ensure secret tokens are retrieved from environment variables, not hardcoded in the source code.
[Medium] GraphQL Introspection POST /graphql src/app.module.ts Attempted fix: Disabled GraphQL introspection in the server configuration to prevent schema exposure.
[Medium] GraphQL Introspection POST /graphql src/app.module.ts Attempted fix: Disabled GraphQL introspection in the server configuration to prevent schema exposure.
Workflow execution details
  • Repository Analysis: TypeScript, NestJS
  • Entrypoints Discovery: 61 entrypoints found
  • Attack Vectors Identification
  • E2E Security Tests Generation: 61 test files generated
  • E2E Security Tests Execution: 19 vulnerabilities found
  • Cleanup Irrelevant Test Files: 45 test files removed
  • Applying Security Fixes: 19 fixes generated
  • Workflow Wrap-Up

@bright-security-golf bright-security-golf bot force-pushed the bright/865d55fa-c8b6-4d8f-a46f-fa7da5062660 branch from 76ffcc6 to 7850fa7 Compare January 14, 2026 08:45
throw new Error('cannot delete file from this location');
} else {
file = path.resolve(process.cwd(), file);
await fs.promises.unlink(file);

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.

Copilot Autofix

AI about 1 month ago

In general, to fix uncontrolled path usage you must (1) decide on a safe root directory, (2) resolve the user-supplied path against that root, (3) normalize / canonicalize it (e.g., with path.resolve and optionally fs.realpath), and (4) reject the operation if the final path is outside the root. Alternatively, for very restrictive APIs, you can sanitize to a simple filename or use an allow‑list of patterns.

For this codebase, the least invasive fix that preserves existing behavior is to keep using process.cwd() as the logical root, but enforce that after resolving, the target path is still within that root. That means in FileService.deleteFile, after file = path.resolve(process.cwd(), file);, we compute const root = path.resolve(process.cwd()); and verify file.startsWith(root + path.sep) or equals root. If it does not, we throw an error (or a 400/403 via InternalServerErrorException is already used). This prevents ../ tricks from escaping the working directory while keeping relative paths functional. Optionally, we can apply the same containment check in getFile for the non-absolute, non-HTTP branch to make reading consistent and safe.

Concretely:

  • Edit src/file/file.service.ts.
  • In deleteFile, introduce a const rootDir = path.resolve(process.cwd()); before resolving file, then resolve file against rootDir, and add a containment check before calling fs.promises.unlink.
  • Similarly, in getFile, for the else branch (relative paths), resolve against rootDir and add the same containment check before fs.promises.access / createReadStream.
  • No new methods or external libraries are required; we only use Node’s built‑in path (already imported) and fs.
Suggested changeset 1
src/file/file.service.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/file/file.service.ts b/src/file/file.service.ts
--- a/src/file/file.service.ts
+++ b/src/file/file.service.ts
@@ -26,8 +26,13 @@
         throw new Error(`no such file or directory, access '${file}'`);
       }
     } else {
-      file = path.resolve(process.cwd(), file);
+      const rootDir = path.resolve(process.cwd());
+      file = path.resolve(rootDir, file);
 
+      if (!file.startsWith(rootDir + path.sep) && file !== rootDir) {
+        throw new Error('access to this location is not allowed');
+      }
+
       await fs.promises.access(file, R_OK);
 
       return fs.createReadStream(file);
@@ -41,7 +45,13 @@
       } else if (file.startsWith('http')) {
         throw new Error('cannot delete file from this location');
       } else {
-        file = path.resolve(process.cwd(), file);
+        const rootDir = path.resolve(process.cwd());
+        file = path.resolve(rootDir, file);
+
+        if (!file.startsWith(rootDir + path.sep) && file !== rootDir) {
+          throw new Error('cannot delete file from this location');
+        }
+
         await fs.promises.unlink(file);
         return true;
       }
EOF
@@ -26,8 +26,13 @@
throw new Error(`no such file or directory, access '${file}'`);
}
} else {
file = path.resolve(process.cwd(), file);
const rootDir = path.resolve(process.cwd());
file = path.resolve(rootDir, file);

if (!file.startsWith(rootDir + path.sep) && file !== rootDir) {
throw new Error('access to this location is not allowed');
}

await fs.promises.access(file, R_OK);

return fs.createReadStream(file);
@@ -41,7 +45,13 @@
} else if (file.startsWith('http')) {
throw new Error('cannot delete file from this location');
} else {
file = path.resolve(process.cwd(), file);
const rootDir = path.resolve(process.cwd());
file = path.resolve(rootDir, file);

if (!file.startsWith(rootDir + path.sep) && file !== rootDir) {
throw new Error('cannot delete file from this location');
}

await fs.promises.unlink(file);
return true;
}
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

Comments