← Back to practice and write-ups

Intigriti LeakyJar · CSRF · Resolved · Medium

LeakyJar: CSRF in vault sharing

I used a cross-site request to make the challenge administrator share their private vault. The browser sent their session cookie with the request, and the sharing endpoint did not check for a CSRF token.

What was the challenge?

LeakyJar stored private recipes in a user vault. Its sharing feature accepted a username at /share and granted that account access to the current user's vault. The goal was to make an administrator share the protected vault with the attacker's account.

The two conditions

The attack depended on two behaviors being present at the same time:

  1. The session cookie used SameSite=None, allowing it to accompany a cross-site request.
  2. The /share endpoint accepted a state-changing POST without requiring a CSRF token.

Neither condition required reading the administrator's response. The browser only needed to send a valid authenticated request containing the attacker's username.

Proof of concept

An attacker-controlled page could submit a form to the challenge endpoint as soon as the administrator visited it:

<form id="share-form"
      action="https://leakyjar.intigriti.io/share"
      method="POST">
  <input name="username" value="guestx">
</form>

<script>
  document.getElementById("share-form").submit();
</script>

The value guestx represented the attacker's challenge account. When the administrator opened the hosted page, the browser sent the POST request with the administrator's session cookie. The application then shared the administrator's vault with the attacker-controlled account.

Impact

The forged request changed access to private data. After the vault was shared, the attacker could open the administrator's recipes and retrieve the challenge flag. The weakness was submitted as cross-site request forgery at medium severity and was later archived as resolved.

Remediation

  • Require a server-generated CSRF token for the sharing action.
  • Use SameSite=Lax or SameSite=Strict when cross-site session use is unnecessary.
  • Validate the request's Origin or Referer header as an additional defense.
  • Consider confirmation or reauthentication before granting another account access to private data.

Key lessons

  • Cookie policy and endpoint protection must be evaluated together.
  • A POST request is not protected from CSRF simply because JavaScript cannot read its response.
  • Sharing and permission changes deserve stronger safeguards than ordinary navigation.
  • A short proof of concept is strongest when it clearly connects browser behavior to the resulting state change.