CVE-2025-68671

Groundhog Day in the Data Lake: Infinite Replay in lakeFS (CVE-2025-68671)

Alon Barad
Alon Barad
Software Engineer

Jan 15, 2026·6 min read

Executive Summary (TL;DR)

The lakeFS S3 gateway correctly verified cryptographic signatures but ignored the timestamp. This means any valid request (including presigned URLs meant to expire in minutes) captured by an attacker could be replayed forever to read, write, or delete data, effectively breaking the temporal security model of AWS SigV4.

A critical authentication bypass in lakeFS's S3 gateway allowed attackers to replay captured requests indefinitely due to missing timestamp validation in the AWS Signature V4 implementation.

The Hook: Time is a Flat Circle

In the world of cryptography, time isn't just a suggestion; it's a security control. When you authenticate with a stateless protocol like AWS S3, you aren't logging in with a session cookie. You are signing every single request with a secret key and, crucially, a timestamp.

This timestamp prevents 'Replay Attacks'. Without it, if I overhear you saying "Open the pod bay doors, HAL" to the server today, I can record that command and play it back to the server next week, next year, or ten years from now. The server, seeing a valid signature, should check its watch and say, "Nice try, Dave, but that command is ancient history."

lakeFS, the popular 'Git for Data' platform, acts as an S3 gateway. It allows tools designed for AWS S3 to interact with versioned data lakes. It implements the complex AWS Signature Version 4 (SigV4) protocol. It did the hard part—the HMAC-SHA256 math—perfectly. But in a classic example of 'missing the forest for the trees', it forgot to look at the clock. Until version 1.75.0, lakeFS lived in a timeless void where every request ever made was valid forever.

The Flaw: The Zombie Request

The vulnerability (CVE-2025-68671) lies in the pkg/gateway/sig package of lakeFS. To understand the gravity of this, you have to understand how AWS SigV4 works. It essentially asks the client to create a string resembling:

AWS4-HMAC-SHA256 20250115T000000Z ...

The client hashes this with their Secret Access Key. The server receives the request, finds the Access Key ID, looks up the corresponding Secret Key, and performs the same math. If the hashes match, the request is authentic.

However, authenticity does not equal timeliness. A check signed in 1990 is authentic, but you probably shouldn't cash it today. Standard S3 implementations enforce a strict "Clock Skew" window—usually 15 minutes. If the X-Amz-Date header is more than 15 minutes away from the server's time.Now(), the request is rejected.

lakeFS simply didn't perform this check. It validated that you signed the request, but it didn't care when you signed it. This turns every intercepted API call into a permanent weapon. Did you upload a sensitive file? An attacker can replay that upload to overwrite newer versions. Did you delete a file? They can delete it again, and again, every time you try to restore it.

The Code: The Missing If-Statement

Let's look at the "before" and "after" code. This is a textbook example of how logic bugs slip past code review because the code looks like it's doing work.

In the vulnerable version of pkg/gateway/sig/v4.go, the code focused entirely on cryptographic parsing:

// BEFORE: Focusing only on the math
func (ctx *verificationCtx) Verify() error {
    // ... extracts headers ...
    // ... calculates HMAC ...
    if !hmac.Equal(calculatedSignature, providedSignature) {
        return errors.ErrSignatureDoesNotMatch
    }
    return nil // LGTM! Ship it!
}

The fix, introduced in commit 92966ae611d7f1a2bbe7fd56f9568c975aab2bd8, adds the necessary temporal logic. They introduced a new method verifyExpiration that actually checks the wall clock:

// AFTER: Adding the clock check
func (ctx *verificationCtx) verifyExpiration() error {
    // ... parse amzDate ...
    now := time.Now().UTC()
    timeDiff := now.Sub(requestTime)
 
    // 1. Check for standard clock skew (15 mins)
    if timeDiff < 0 && timeDiff.Abs() > AmzMaxClockSkew {
         return errors.ErrRequestNotReadyYet
    }
 
    // 2. Check for Presigned URL expiration
    if ctx.AuthValue.IsPresigned {
        expirationTime := requestTime.Add(time.Duration(ctx.AuthValue.Expires) * time.Second)
        if now.After(expirationTime) {
            return errors.ErrExpiredPresignRequest
        }
    }
    return nil
}

The patch also had to propagate this error up the chain in pkg/gateway/sig/sig.go. Previously, a failed check might have just fallen through; now, an expired request is hard-stopped.

The Exploit: Eternal Presigned URLs

The most dangerous aspect of this flaw involves Presigned URLs. These are magic URLs generated by S3 compatible systems that allow temporary access to a specific object without credentials. They are heavily used in automated workflows: "Here is a link to upload your CSV; it expires in 5 minutes."

In vulnerable versions of lakeFS, the X-Amz-Expires parameter was ignored. That 5-minute link? It's valid forever.

Attack Scenario:

  1. Reconnaissance: The attacker monitors network traffic (MITM) or gains read-access to server logs where full URLs are often stored.
  2. Capture: The attacker sees a PUT request generated by a CI/CD pipeline deploying a new model: https://lakefs.corp/api/v1/repositories/models/main/production.pkl?X-Amz-Algorithm=...&X-Amz-Expires=300...
  3. Wait: The attacker waits 6 months. The data scientists have updated the model 50 times since then.
  4. Strike: The attacker replays the exact URL from step 2.
    curl -X PUT "https://lakefs.corp/api/v1/repositories/models/main/production.pkl?X-Amz-Algorithm=..." --data-binary @old_compromised_model.pkl
  5. Result: lakeFS accepts the request. The production model is silently rolled back to the old version (or a malicious one if the attacker could manipulate the body content while preserving the hash, though SigV4 usually protects the body, replay of the original body is the threat here).

The Impact: Why You Should Care

This vulnerability breaks the fundamental promise of temporary access.

1. Security Bypass: If you grant a vendor temporary access to your data lake to perform an audit, they theoretically retain that access forever (until you rotate the underlying Access Keys).

2. Data Integrity: As noted in the exploit scenario, replay attacks are often used to revert state. An attacker can undo critical updates or re-delete restored data.

3. Compliance Nightmares: Many compliance standards require strict access windows. A system that honors a token issued in 2024 during an audit in 2030 is fundamentally non-compliant.

The only saving grace is that SigV4 includes the request payload hash in the signature (for PUT requests usually). This means the attacker cannot modify the content of the file being uploaded, they can only re-upload the exact same file that was originally sent. However, for DELETE or GET requests, the impact is immediate and high.

Mitigation: Closing the Loop

The fix is straightforward, but it requires action.

1. Patch Immediately: Upgrade to lakeFS v1.75.0 or later. This introduces the verifyExpiration logic shown above.

2. Rotate Your Keys: This is critical. Patching the code stops new weirdly-dated requests, but if an attacker has already captured a valid signature for your current Access Key, they might still try to use it (though the new code will now reject it based on the date). However, to be absolutely safe and invalidate all historical signatures floating in logs, rotate the AWS Access Keys used by your users and services.

3. Short-Term Network Blocks: If you cannot patch immediately, restrict access to the S3 Gateway port to trusted internal IP addresses only. This reduces the surface area for a capture-and-replay attack.

Fix Analysis (1)

Technical Appendix

CVSS Score
7.4 (Estimated)/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

lakeFS S3 Gateway

Affected Versions Detail

Product
Affected Versions
Fixed Version
lakeFS
Treeverse
<= 1.74.41.75.0
AttributeDetail
CWE IDCWE-294
Attack VectorNetwork (Replay)
ImpactAuthentication Bypass / Data Integrity
CVSS (Est)7.4 (High)
StatusPatched
Clock Skew Limit15 Minutes (Post-Fix)
CWE-294
Authentication Bypass by Capture-replay

Authentication Bypass by Capture-replay

Vulnerability Timeline

Issue Reported
2025-10-23
Fix Merged
2025-12-02
Public Disclosure
2026-01-15

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.