How Neo found an SSRF vulnerability in Faraday, and why it matters for every team that ships code
嗯,这篇文章讲的是Neo发现了Faraday中的SSRF漏洞。Faraday是一个Ruby生态系统中常用的HTTP客户端库。Neo是ProjectDiscovery的人工智能安全助手,专门用于代码审查和漏洞发现。 文章提到,Neo在没有人工指导的情况下,审查了一个广泛使用的开源依赖项,发现了一个微妙的URL处理边缘情况,并在运行时验证了它,还生成了一个清晰的报告供维护人员修复。这个漏洞是通过以两个斜杠开头的URL(如//evil.com)来覆盖目标主机的。 文章还讨论了传统扫描工具如Snyk和Semgrep在这类问题上的局限性,因为它们主要依赖模式匹配,而这类漏洞隐藏在看似安全的逻辑中。Neo的优势在于能够像人类审查员一样进行推理,发现传统工具难以捕捉到的漏洞。 最后,文章强调了这类漏洞的重要性以及使用AI工具如Neo进行早期检测的好处,可以节省时间和资源。 </think> 文章描述了人工智能助手Neo发现并修复了Ruby生态系统中广泛使用的HTTP客户端库Faraday中的一个服务器端请求伪造(SSRF)漏洞。该漏洞通过以两个斜杠开头的URL(如//evil.com)覆盖目标主机。Neo无需人工指导,独立完成了代码审查、漏洞验证和修复建议。传统扫描工具难以捕捉此类隐藏在正常逻辑中的边缘情况,而Neo通过推理和验证提供了可复现的证据。这一发现展示了AI在安全审查中的潜力,帮助开发团队更早地识别和修复潜在的安全风险。 2026-3-3 17:5:32 Author: projectdiscovery.io(查看原文) 阅读量:0 收藏

Executive Summary

Neo found a Server-Side Request Forgery (SSRF) vulnerability in Faraday, a widely used HTTP client library in the Ruby ecosystem. This is Neo’s first credited CVE discovery.

Neo is ProjectDiscovery’s AI security copilot for tasks like code review and vulnerability discovery. For this finding, Neo reviewed a widely used open source dependency and, without human guidance, surfaced a subtle URL-handling edge case, validated it in runtime, and produced a clear write-up that maintainers could patch.

Takeaway: Neo accomplished the type of deep review that can take senior engineers hours to complete. When you apply the same workflow for code review, Neo can save security teams significant time while catching critical security risks before they hit production.

Finding snapshot

Background: what is Faraday and what is an SSRF vulnerability

Faraday is one of the most common HTTP client libraries in the Ruby ecosystem, so it sits in the critical path of how Ruby applications make outbound requests. Faraday is also widely used, with 5.9k GitHub stars, 1.1 billion downloads, and packaged as part of applications including GitLab, Fastlane, and Google Auth.

SSRF, or Server-Side Request Forgery, is when an attacker can steer where your server sends an outbound request by supplying input that looks harmless, but changes the real destination.

Scanners often miss SSRF because it is usually a logic and URL parsing edge case, not a single “dangerous function.” For example, code may try to lock requests to a trusted base URL, but an input like //evil.com/path can be treated by URL libraries as “use this host,” not “use this path.” To confirm SSRF, you have to trace the input to the final request destination and verify where the server actually goes. These issues often slip past scanners and only get discovered during deep review by engineers.

How Neo found an SSRF in Faraday

Neo began reviewing Faraday’s code like a human

Neo did not start the way most scanners do, by pattern matching for obviously risky calls like eval or exec. Those checks are useful for catching common classes of bugs, but they are not how a human reviewer finds the more obscure issues that hide in normal, safe-looking code.

Instead, Neo mapped the full codebase and then narrowed its attention to the handful of files that control URL building and request routing. In Faraday, that meant starting with connection.rb and the URL and request helpers, because that is where a trusted base URL and a caller-provided path turn into a real outbound request.

That approach matters because subtle vulnerabilities tend to appear when two pieces of correct behavior interact in an unexpected way as we’ll see below.

Tracing the URL logic and showing the bypass

Once Neo built a map of the repo, it looked for the choke point where Faraday turns two inputs into a destination: a trusted base URL and a caller-provided path. That trail led to build_exclusive_url in connection.rb, because it is the function responsible for combining those values into the final request URL.

Inside that method, Neo found what looks like a reasonable safety check: Faraday prevents callers from overriding the base URL with a full absolute URL by checking how the input starts. If the input looks like an absolute URL, it is treated differently. If it looks like a normal path, it is allowed.

However, the check intentionally allows inputs that start with /, because apps need to pass paths like /api/v1/users. But there is a special kind of URL that also starts with / and is easy to miss if you are not thinking about how URL libraries interpret it: a URL that starts with two slashes, like //evil.com/steal.

Neo recognized that this form is not “just a path.” Under the rules browsers and URL libraries follow, //evil.com/steal is treated as “use this host,” while inheriting the scheme from the base URL. So when Faraday merges:

  • base: https://api.internal.com
  • path: //evil.com/steal

the result can become:

  • https://evil.com/steal

In other words, a value that passes a “starts with /” allowlist can still change the destination host.

A minimal trigger looks like this:

If an attacker can influence that path value, they can redirect where the server sends requests. That is SSRF.

From finding to fix

Neo did not stop at “this looks suspicious.” It documented the issue in a way a human could act on, including the exact code path, a minimal reproducer, the conditions required for impact, and a clear remediation direction. That matters because the hard part of security review is turning findings into something reproducible that can be patched. With this report, the maintainers were able to confirm the behavior and ship a fix, which became CVE-2026-25765.

What Snyk and Semgrep caught and what they missed

To see if whether traditional scanners would have caught this, we ran the Faraday repo through Snyk SAST and Semgrep.

Snyk did not surface any issues for this snapshot.

Semgrep did return findings, but they were unrelated to URL construction. The results we saw were low-severity shell hygiene findings in scripts, which is expected. Tools like Snyk and Semgrep are strongest at repeatable pattern coverage, while this issue lives in safe-looking logic and an edge case most rulesets do not model.

This is not a knock on Snyk nor Semgrep. Scanners like these are designed to catch broad classes of known issues using consistent rules, but some vulnerabilities do not look like “bad code” in isolation. They hide in safe-looking logic and only show up when you reason through edge cases and how the pieces behave together. That is the gap Neo is built to fill: it can do that reviewer-style reasoning autonomously, then hand you a concrete, reproducible finding instead of a generic alert.

Why this matters

Security issues often hide in edge cases. They live in code that looks reasonable and passes review because the failure is an assumption that breaks when normal pieces interact, like URL handling rules plus a guardrail meant to keep requests safe.

Traditional scanners are valuable for broad, consistent coverage, but they rarely catch these behavior gaps reliably. Historically, teams have covered that gap with senior manual review, pentests, and bug bounty research, but those solutions are expensive and hard to apply everywhere without slowing development.

The Faraday SSRF is a good example. Neo traced the code path that determines where requests go, identified an edge case that changes the destination, validated it in runtime, and documented it with a minimal repro and fix direction that maintainers could confirm and patch.

If this kind of bug can survive in a mature dependency, it can exist in internal URL and request-handling code too, and the work to catch it does not need to be purely manual anymore. Tools that can reason through code and return reproducible evidence move this class of review earlier, when fixes are cheaper, faster, and less disruptive.

Want Neo to run this kind of review on your code and dependencies? Request a demo


文章来源: https://projectdiscovery.io/blog/how-neo-found-an-ssrf-vulnerability-in-faraday-and-why-it-matters-for-every-team-that-ships-code
如有侵权请联系:admin#unsafe.sh