Skip to content

feat: add resolve vulnerability claude 3.7 model

What does this merge request do and why?

Adds a new Claude 3.7 prompt to the prompt registry for resolve vulnerability

How to set up and validate locally

  • Request the resolve_vulnerability endpoint
curl -X 'POST' \
  'http://gdk.test:5052/v1/prompts/resolve_vulnerability' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'x-gitlab-enabled-feature-flags: expanded_ai_logging' \
  -d '{
  "inputs": {
    "name": "SQL Injection in User Query",
    "vulnerability_description": "An SQL injection vulnerability was detected in the user search functionality. The application directly concatenates user input into SQL queries without proper sanitization or parameterization, allowing potential attackers to manipulate the query structure and access unauthorized data.",
    "identifiers": "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('"'"'SQL Injection'"'"')\nCVSS Score: 8.5 (High)",
    "filename": "user_service.js",
    "source_code": "const express = require('"'"'express'"'"');\nconst mysql = require('"'"'mysql'"'"');\nconst router = express.Router();\n\n// Database connection\nconst connection = mysql.createConnection({\n  host: '"'"'localhost'"'"',\n  user: '"'"'appuser'"'"',\n  password: process.env.DB_PASSWORD,\n  database: '"'"'userdb'"'"'\n});\n\nconnection.connect();\n\n// Get user by ID\nrouter.get('"'"'/user/:id'"'"', (req, res) => {\n  const userId = req.params.id;\n  const query = `SELECT * FROM users WHERE id = ${userId}`;\n  \n  connection.query(query, (error, results) => {\n    if (error) throw error;\n    res.json(results[0]);\n  });\n});\n\n// Search users by name\nrouter.get('"'"'/search'"'"', (req, res) => {\n  const searchTerm = req.query.name;\n  const query = `SELECT * FROM users WHERE name LIKE '"'"'%${searchTerm}%'"'"'`;\n  \n  connection.query(query, (error, results) => {\n    if (error) throw error;\n    res.json(results);\n  });\n});\n\n// Add new user\nrouter.post('"'"'/user'"'"', (req, res) => {\n  const { name, email, role } = req.body;\n  const query = '"'"'INSERT INTO users (name, email, role) VALUES (?, ?, ?)'"'"';\n  \n  connection.query(query, [name, email, role], (error, results) => {\n    if (error) throw error;\n    res.status(201).json({ id: results.insertId });\n  });\n});\n\nmodule.exports = router;",
    "vulnerable_code": "router.get('"'"'/user/:id'"'"', (req, res) => {\n  const userId = req.params.id;\n  const query = `SELECT * FROM users WHERE id = ${userId}`;\n  \n  connection.query(query, (error, results) => {\n    if (error) throw error;\n    res.json(results[0]);\n  });\n});\n\n// Search users by name\nrouter.get('"'"'/search'"'"', (req, res) => {\n  const searchTerm = req.query.name;\n  const query = `SELECT * FROM users WHERE name LIKE '"'"'%${searchTerm}%'"'"'`;\n  \n  connection.query(query, (error, results) => {\n    if (error) throw error;\n    res.json(results);\n  });\n});"
  },
  "prompt_version": "0.0.1-dev",
  "stream": false
}'
  • Tail the following logs to ensure the "Claude 3.7" model is called: gdk tail gitlab-ai-gateway | grep "Request to LLM"

  • Ensure the response is valid for the following tool

"<analysis>\nThe vulnerability report identifies SQL Injection (CWE-89) in the user search functionality. After examining the code, I can confirm this is a legitimate vulnerability.\n\nThe vulnerable code sections are:\n\n1. In the `/user/:id` endpoint:\n```javascript\nconst userId = req.params.id;\nconst query = `SELECT * FROM users WHERE id = ${userId}`;\n```\n\n2. In the `/search` endpoint:\n```javascript\nconst searchTerm = req.query.name;\nconst query = `SELECT * FROM users WHERE name LIKE '%${searchTerm}%'`;\n```\n\nIn both cases, user input (`userId` and `searchTerm`) is directly concatenated into SQL queries without proper sanitization or parameterization. This allows attackers to inject malicious SQL code that could:\n\n1. Bypass authentication\n2. Access unauthorized data\n3. Modify database content\n4. Execute administrative operations\n5. In some cases, access the underlying server\n\nFor example, an attacker could send a request to `/user/1 OR 1=1` which would result in the query `SELECT * FROM users WHERE id = 1 OR 1=1`, returning all users in the database.\n\nInterestingly, the code already demonstrates proper parameterized queries in the POST endpoint:\n```javascript\nconst query = 'INSERT INTO users (name, email, role) VALUES (?, ?, ?)';\nconnection.query(query, [name, email, role], ...);\n```\n\nThis is the correct approach that should be applied to the other endpoints as well.\n</analysis>\n\n<fixed_code>\n<old_code>\n// Get user by ID\nrouter.get('/user/:id', (req, res) => {\n  const userId = req.params.id;\n  const query = `SELECT * FROM users WHERE id = ${userId}`;\n  \n  connection.query(query, (error, results) => {\n    if (error) throw error;\n    res.json(results[0]);\n  });\n});\n</old_code>\n<new_code>\n// Get user by ID\nrouter.get('/user/:id', (req, res) => {\n  const userId = req.params.id;\n  const query = 'SELECT * FROM users WHERE id = ?';\n  \n  connection.query(query, [userId], (error, results) => {\n    if (error) throw error;\n    res.json(results[0]);\n  });\n});\n</new_code>\n\n<old_code>\n// Search users by name\nrouter.get('/search', (req, res) => {\n  const searchTerm = req.query.name;\n  const query = `SELECT * FROM users WHERE name LIKE '%${searchTerm}%'`;\n  \n  connection.query(query, (error, results) => {\n    if (error) throw error;\n    res.json(results);\n  });\n});\n</old_code>\n<new_code>\n// Search users by name\nrouter.get('/search', (req, res) => {\n  const searchTerm = req.query.name;\n  const query = 'SELECT * FROM users WHERE name LIKE ?';\n  \n  connection.query(query, [`%${searchTerm}%`], (error, results) => {\n    if (error) throw error;\n    res.json(results);\n  });\n});\n</new_code>\n</fixed_code>\n\n<is_false_positive>\nfalse\n</is_false_positive>\n\n<summary>\n## SQL Injection Vulnerability Fix\n\n### Vulnerability\nThe code contained SQL injection vulnerabilities (CWE-89) in two endpoints:\n1. `/user/:id` - User ID was directly concatenated into the SQL query\n2. `/search` - Search term was directly concatenated into the SQL query\n\nThese vulnerabilities could allow attackers to manipulate the SQL queries to access unauthorized data, bypass authentication, or even potentially execute commands on the database server.\n\n### Fix Implementation\nI replaced the vulnerable string concatenation with parameterized queries:\n\n1. For the user ID endpoint:\n```javascript\n// Before\nconst query = `SELECT * FROM users WHERE id = ${userId}`;\nconnection.query(query, (error, results) => { ... });\n\n// After\nconst query = 'SELECT * FROM users WHERE id = ?';\nconnection.query(query, [userId], (error, results) => { ... });\n```\n\n2. For the search endpoint:\n```javascript\n// Before\nconst query = `SELECT * FROM users WHERE name LIKE '%${searchTerm}%'`;\nconnection.query(query, (error, results) => { ... });\n\n// After\nconst query = 'SELECT * FROM users WHERE name LIKE ?';\nconnection.query(query, [`%${searchTerm}%`], (error, results) => { ... });\n```\n\nThese changes ensure that user input is properly escaped and treated as data rather than executable code, preventing SQL injection attacks while maintaining the original functionality. The fix follows the same pattern already used in the POST endpoint of the application, which was correctly using parameterized queries.\n</summary>"%   

Merge request checklist

  • Tests added for new functionality. If not, please raise an issue to follow up.
  • Documentation added/updated, if needed.

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/523496

Edited by Nathan Weinshenker

Merge request reports

Loading