SSRF in GitLab Import-URL Feature Enabling Internal Network Probing

SSRF in GitLab Import-URL Feature Enabling Internal Network Probing

November 21, 2025 7 min read

A security researcher uncovered an SSRF flaw in GitLab’s import-from-URL feature that enabled internal port probing.




Disclaimer

This article is strictly for educational and defensive cybersecurity purposes.
All tests were performed in a legally authorized lab environment.
Never test systems you do not own or do not have explicit permission to assess.


Introduction

Server-Side Request Forgery (SSRF) remains one of the most impactful yet misunderstood vulnerabilities affecting modern DevOps platforms. Applications like GitLab, GitHub Enterprise, and CI/CD automation tools frequently interact with remote resources, making them attractive targets for SSRF-based attacks when input validation is insufficient.

In this documented case, a security researcher discovered a Server-Side Request Forgery flaw inside the “Import Project → From URL” functionality of a GitLab Self-Hosted installation. Although GitLab later marked the report as a duplicate, this finding demonstrated how a seemingly simple SSRF - initially capable only of triggering a single outbound request - can escalate into a full-fledged internal network scanner due to observable timing differences.

This blog breaks down the vulnerability, explains the reproduction steps, presents safe technical details, and shows effective mitigation strategies for DevOps engineers, security teams, and bug hunters.

A minimalistic cybersecurity diagram showing a GitLab server receiving a user-provided URL and issuing an unintended outbound HTTP request, illustrating the Server-Side Request Forgery (SSRF) concept with clean lines and a blue palette.


Understanding the GitLab Import-URL SSRF Setup

The GitLab Import Project feature allows users to clone remote repositories directly using a URL. In a typical workflow, a user enters a Git repository URL, and GitLab internally performs a server-side HTTP request to pull metadata.

However, this feature can become vulnerable when:

  • The application does not validate URLs properly
  • No allowlist or blocklist rules define safe domains
  • The GitLab server is allowed to make unrestricted egress requests
  • Internal network ranges (127.x.x.x / 10.x.x.x / 192.168.x.x) are not blocked

Under these conditions, a malicious user may bypass the intended behavior and force GitLab to make network calls to internal servers, metadata endpoints, or unknown services.


Step 1 - Recon & Discovery

The researcher began by understanding how the GitLab import feature behaves under normal conditions.

Observed Behavior

When a URL is provided, GitLab immediately performs a server-side request to fetch repository data. This server-originated request is sent before user input is validated.

To confirm SSRF feasibility, the researcher:

  1. Set up a Burp Collaborator server (or any HTTP listener).
  2. Opened GitLab → Import Project → From URL.
  3. Entered the callback server URL (e.g., http://collab.example.com/test).
  4. Observed DNS + HTTP callbacks on the collaborator interface.

This validated that GitLab was indeed issuing outbound requests on behalf of the user.

Beginner Breakout: What Is SSRF?

Server-Side Request Forgery is a vulnerability where an attacker manipulates an application into sending unauthorized requests from the server itself. Because the request originates internally, it can reach systems not normally exposed to the internet - such as admin panels, internal APIs, and cloud metadata endpoints.

Screenshot of Burp Collaborator showing DNS/HTTP callbacks confirming a Server-Side Request Forgery (SSRF) vulnerability.


Step 2 - Understanding the Vulnerability

Although at first glance the issue appears to be a basic blind SSRF, additional analysis revealed a more dangerous property:
GitLab behaved differently based on whether the target port responded or not.

This allowed the researcher to not just trigger a single unauthorized request but to scan arbitrary internal IPs and ports, turning the GitLab instance into a reconnaissance tool.

Key indicators:

  • Changes in response time
  • Variations in response length
  • Distinct HTTP status codes

These behavioral differences acted as measurable indicators of an open vs. closed port.

Why This Matters

With SSRF alone, impact may be limited to reading metadata or probing one URL.
But with timing-based side-channel signals, the attacker gains the ability to:

  • Map the internal network
  • Discover internal admin interfaces
  • Fingerprint services (MySQL, Redis, Jenkins, etc.)
  • Identify attack surfaces for lateral movement

This elevates the severity significantly.

Burp Intruder configuration screen with payload positions highlighting the modification of the 'import_url' parameter for SSRF testing.


Step 3 - Building the Exploit (Safe, High-Level)

The researcher then attempted to turn this SSRF into a network scanner. All testing was done on an authorized, isolated lab environment.

3.1 Intercepting the Import Request

Using Burp Suite:

  1. Trigger the import request.
  2. Intercept the HTTP request (typically sent to a path such as /import_project/validate).
  3. Identify the parameter containing the repository URL - often named import_url.

This parameter is the injection point for SSRF.

3.2 Configuring Intruder

In Burp Intruder:

  • Clear default insertion points.
  • Add a payload position around the port.

Example test URL (lab environment):

http://10.0.0.5:§80§/

Then configure a number payload to iterate through ports 1-1024.

3.3 Launching the Attack (Lab Only)

When Intruder begins its scan, GitLab:

  • Reads the user-crafted URL
  • Attempts to connect to the specified port
  • Returns a measurable response

A difference in response length, delay, or status code indicates an open port.

Beginner Breakout: Why Response Length Varies

Closed ports often fail instantly or trigger connection-refused errors.
Open ports may return banners, redirects, or partial payloads - changing the total response length.

This subtle difference becomes a powerful scanning signal.

Burp Intruder results illustrating a distinct response length on a specific internal port, indicating successful network probing.

A technical illustration of port-scanning logic using an automated request sequence, showing arrows indicating sequential port enumeration via a modified URL parameter in a blue cyber-theme.


Step 4 - Executing & Confirming the Exploit

Once the Intruder attack was underway, the researcher observed:

  • Most ports returned consistent response lengths (indicating closed ports).
  • Certain ports produced longer or shorter responses, confirming open ports.
  • One request showed a distinct response pattern, confirming successful internal probing.

Through these differences, the researcher identified a responsive service on the internal network - something unreachable from the outside world.

This ultimately demonstrated that GitLab's import functionality could serve as a proxy into the internal network.

Raw HTTP request and response pair confirming the successful probing of an internal network port via SSRF.

A side-channel timing visualization comparing fast closed-port responses versus slower open-port responses using simple bar graphs in a cybersecurity theme with blue tones.


Defensive Perspective

This vulnerability showcases how DevOps platforms - especially self-hosted environments - can become dangerous pivot points without proper filtering.

Application-Level Mitigations

1. Implement Strict Allowlisting

Only approved domains should be permitted as import sources:

  • GitHub
  • GitLab.com
  • Internal Git mirrors

Reject all other hosts at the application layer.

2. Block Access to Internal IP Ranges

GitLab should reject URLs in:

  • 127.0.0.0/8
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
  • 169.254.169.254 (cloud metadata services)

This can be implemented using IP parsing and validation.

3. Enforce Outbound Proxy Controls

Route all import requests through a security-hardened proxy.
The proxy becomes the enforcement point for:

  • Domain restrictions
  • Port restrictions
  • Traffic monitoring

4. Apply Strict Timeouts

Short connection and read timeouts prevent timing-based reconnaissance.

A layered diagram representing defense-in-depth, showing application-layer allowlist, outbound proxy controls, and firewall restrictions working together in a modern flat design with a blue gradient.


Infrastructure-Level Mitigations

1. Egress Firewall Rules

The server hosting GitLab should not have unrestricted outbound access.

Firewall policies should:

  • Block access to all RFC1918 subnets
  • Allow only essential outbound requests
  • Restrict traffic to metadata services

2. Harden Cloud Metadata Access

Cloud platforms provide instance metadata at predictable IPs.
Locking these behind IMDSv2 or firewall controls is essential for protecting:

  • IAM credentials
  • API tokens
  • Instance metadata

Real-World Example

An attacker exploiting SSRF in Jira once gained access to AWS metadata, obtained IAM keys, and accessed sensitive cloud resources. The GitLab issue documented here demonstrates similar risk if not mitigated correctly.


Real-World Impact

Even though GitLab marked the submission as a duplicate, the researcher’s reproduction demonstrated elevated severity due to internal port scanning capability.

Impact summary:

Type Description
SSRF GitLab server sends attacker-supplied requests
Internal Recon Identify live hosts and open ports
Pivoting Risk Potential discovery of admin panels or services
Service Fingerprinting Detecting MySQL, Jenkins, Redis, etc.
Cloud Metadata Risk of token exposure if metadata endpoints are reachable

In well-connected enterprise networks, such SSRF flaws can be the first step in:

  • Privilege escalation
  • Lateral movement
  • Infrastructure takeover

Troubleshooting & Pitfalls

1. No Visible Callback?

If no callback is received:

  • Firewall may be blocking outbound traffic
  • Proxy settings may intercept HTTP calls
  • URL might be sanitized before sending

2. Stable Response Lengths

Sometimes all responses look identical.
This may indicate:

  • A centralized request handler sanitizes errors
  • Application-level error suppression
  • Timeouts are forcing uniform responses

3. Access Denied for Localhost

Some GitLab builds attempt to block localhost, but partial bypasses may still be possible using:

  • Decimal IP notation
  • IPv6 addresses
  • Mixed formats (localhost.xip.io, 127.1.1.1, etc.)

(For research purposes only - never attempt this outside a lab.)


Final Thoughts

This case serves as an important reminder that SSRF is not just about triggering a request - it’s about what the server can reach internally. When timing differences or response discrepancies reveal port status, SSRF becomes a reconnaissance engine.

Even when a vendor classifies an issue as a duplicate, demonstrating clear internal impact provides crucial evidence that elevates the severity and helps engineering teams prioritize remediation.

By combining safe testing practices, proper validation, egress filtering, and strict network segmentation, organizations can dramatically reduce the risk posed by SSRF vulnerabilities.


References

  • GitLab Security Documentation
  • OWASP SSRF Prevention Cheat Sheet
  • Burp Suite Professional (Intruder, Collaborator)
  • RFC1918 Private Address Space

Join the Security Intel.

Get weekly VAPT techniques, ethical hacking tools, and zero-day analysis delivered to your inbox.

Weekly Updates No Spam
Herish Chaniyara

Herish Chaniyara

Web Application Penetration Tester (VAPT) & Security Researcher. A Gold Microsoft Student Ambassador and PortSwigger Hall of Fame (#59) member dedicated to securing the web.

Read Next

View all posts

For any queries or professional discussions: herish.chaniyara@gmail.com