API V2.0.0 Security Patch

Documentation

Guide for using ShortYourLinks Web & API safely and efficiently

Introduction

ShortYourLinks is a high-security URL shortener focused on privacy and anti-bot protection. Your data automatically expires after 30 days for safety.

💡 The system uses a 3-layer security mechanism: Cloudflare Turnstile, One-Time HMAC Tokens, and Silent Failure to absolutely prevent bot spam.

Web Interface Usage

  1. 1. Paste your long URL into the input field on the home page.
  2. 2. Complete Cloudflare Turnstile verification (required to unlock the button).
  3. 3. Click the shorten button and get your link.
  4. 4. Manage your links in the "Manage" section (Tied to your IP address).

Public API Reference

Our API lets you create and manage links from your own apps (Discord Bots, Telegram Bots, automation scripts...).

POST https://shortyourlinks.prmgvyt.xyz/api.php

Required Headers

Content-Type: application/json
X-CSRF-Token:   <csrf_token>
X-Access-Token: <access_token>
X-Signature:    <hmac_sha256_signature>
⚠️ Security tokens are generated automatically on page load and are single-use only. Reload the page to obtain a new token set.

Request Body (JSON):

{
  "action": "create",
  "url": "https://example.com/your-very-long-link-here",
  "cf-turnstile-response": "<turnstile_token>"
}

Success Response 200 OK

{
  "status": "success",
  "message": "Link created successfully.",
  "code": "aB12zX",
  "short_url": "https://shortyourlinks.prmgvyt.xyz/aB12zX",
  "expires": "30 days"
}
⚠️ Note: Links created via API have a 5-second activation delay.

Analytics Tracking

Retrieve click counts and creation date for a specific short code.

Request Body

{
  "action": "analytics",
  "code": "aB12zX",
  "cf-turnstile-response": "<turnstile_token>"
}

Response 200 OK

{
  "status": "success",
  "data": {
    "long_url": "https://example.com/...",
    "created_at": "2026-04-15 08:30:00",
    "clicks": 142
  }
}

API Security

1. One-Time Token Mechanism

Every page load generates a fresh token set (csrf, access_token, signature). Old tokens are invalidated immediately after successful use, preventing Replay Attacks.

2. HMAC-SHA256 Signature Verification

The server recomputes the signature from SESSION data and compares it with the submitted header. Mismatch = immediate rejection.

// Signature formula (server-side)
 $expected = hash_hmac("sha256", $session_csrf . $session_token, $secret);
if (!hash_equals($expected, $submitted_sign)) {
    // → Redirect to 404 (Silent Failure)
}

3. Cloudflare Turnstile

Every request must include a valid Turnstile token. The server verifies it with Cloudflare's API before processing — automated bots and scripts are blocked.

4. Silent Failure (Anti-Enumeration)

Any violating action (Invalid token, Rate limit, Blocked URL) redirects to a 404 Not Found page. This prevents bots from knowing exactly why they were blocked, mitigating enumeration attacks.

🚫 Never hardcode tokens into source code or save them to files. Tokens only live within the session and must be read from DOM at form load time.

Best Practices

✅ Do

• Always check status === "success" before using short_url
• Add a 5-second delay after link creation before redirecting
• Validate URLs client-side (only accept http:// and https://)
• Wrap all fetch calls in try/catch
• Cache the short URL if you shorten the same URL repeatedly

❌ Don't

• Don't call the API in tight loops — rate limiting triggers and hides as 404
• Don't reuse tokens from previous requests — they're already invalidated
• Don't submit javascript:, data:, ftp: URLs — they'll be rejected
• Don't store tokens in localStorage or cookies

JavaScript Example (correct approach)

async function shortenURL(longUrl) {
  // 1. Đọc token từ hidden input (KHÔNG hardcode)
  const csrf      = document.getElementById('_csrf').value;
  const token     = document.getElementById('_token').value;
  const signature = document.getElementById('_sign').value;
  const tsToken   = document.querySelector('[name="cf-turnstile-response"]').value;

  // 2. Validate scheme trước khi gửi
  const url = new URL(longUrl);
  if (!['http:', 'https:'].includes(url.protocol)) {
    throw new Error('Invalid URL scheme');
  }

  // 3. Gọi API
  const res = await fetch('/api.php', {
    method: 'POST',
    headers: {
      'Content-Type':   'application/json',
      'X-CSRF-Token':   csrf,
      'X-Access-Token': token,
      'X-Signature':    signature,
    },
    body: JSON.stringify({
      action: 'create',
      url: longUrl,
      'cf-turnstile-response': tsToken,
    }),
  });

  // Nếu bị 404, có thể do vi phạm bảo mật hoặc lỗi hệ thống
  if (!res.ok) throw new Error('Request failed or blocked');

  const data = await res.json();

  // 4. Kiểm tra status trước khi dùng kết quả
  if (data.status !== 'success') {
    throw new Error(data.message);
  }

  // 5. Đợi 5 giây (activation delay)
  await new Promise(r => setTimeout(r, 5000));

  return data.short_url;
}

Error Handling

ℹ️ For security reasons, the system uses a Silent Failure mechanism. All invalid requests (Wrong token, Rate limit, Blocked URL) return 404 Not Found. Bots cannot determine which step they were blocked at.
Scenario Server Response How to Handle
Invalid / already-used token 404 Not Found Reload page to get fresh tokens
Rate limit exceeded (50 links/week) 404 Not Found Stop sending requests, wait for the next 7-day cycle
Invalid URL / blocked scheme 404 Not Found Only use http:// or https://
Turnstile Captcha verification failed 404 Not Found Verify again that you are not a bot
Successful request 200 OK Receive JSON data and continue processing

Limits & Security

  • 🌐 Web/API: Max 50 links / 7 days per IP.
  • ⏱️ Auto-delete: All links expire after 30 days.
  • 🤖 Bot detection: Cloudflare Turnstile + HMAC signature + Silent Failure automatically blocks automated scripts