Skip to content

Security/fix api token auth#975

Open
Revanza1106 wants to merge 2 commits intoOpenSID:rilis-devfrom
Revanza1106:security/fix-api-token-auth
Open

Security/fix api token auth#975
Revanza1106 wants to merge 2 commits intoOpenSID:rilis-devfrom
Revanza1106:security/fix-api-token-auth

Conversation

@Revanza1106
Copy link

@Revanza1106 Revanza1106 commented Mar 8, 2026

Ringkasan

Memperbaiki kerentanan keamanan kritis #974 dimana endpoint /api/v1/token dapat diakses tanpa autentikasi, memungkinkan siapa saja membuat token API yang valid.

Perubahan yang Dilakukan

1. Proteksi Route (routes/apiv1.php)

Sebelum:

Route::middleware(['auth:sanctum'])->group(function () {
    Route::get('/token', [AuthController::class, 'token']);
    // ...
});

Sesudah:

Route::middleware(['auth:sanctum'])->group(function () {
    Route::middleware(['role:administrator'])->get('/token', [AuthController::class, 'token']);
    // ...
});

2. Peningkatan Controller (app/Http/Controllers/Api/Auth/AuthController.php)

Ditambahkan:

  • Injeksi parameter Request
  • Validasi user synchronize
  • Pencabutan token lama sebelum membuat token baru (best practice keamanan)
  • Logging aktivitas untuk audit trail
  • Penanganan error yang lebih baik

Sebelum:

public function token()
{
    $user = User::whereUsername('synchronize')->first();
    $token = $user->createToken('auth_token', ['synchronize-opendk-create'])->plainTextToken;

    return response()->json(['message' => 'Token Synchronize', 'access_token' => $token, 'token_type' => 'Bearer']);
}

Sesudah:

public function token(Request $request)
{
    // Temukan user synchronize
    $user = User::whereUsername('synchronize')->first();
    
    if (!$user) {
        return response()->json([
            'message' => 'User synchronize tidak ditemukan'
        ], 404);
    }

    // Cabut token yang ada sebelum membuat token baru
    $user->tokens()->delete();
    
    // Buat token baru dengan abilities spesifik
    $token = $user->createToken('auth_token', ['synchronize-opendk-create'])->plainTextToken;

    // Log pembuatan token untuk audit trail
    activity()
        ->performedOn($user)
        ->causedBy(auth()->user())
        ->withProperties([
            'ip' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'token_abilities' => ['synchronize-opendk-create']
        ])
        ->log('token.generated');

    return response()->json([
        'message' => 'Token Synchronize', 
        'access_token' => $token, 
        'token_type' => 'Bearer'
    ]);
}

Checklist Keamanan ✅

Semua item diverifikasi dengan tes otomatis:

  • Request tanpa token → Return 401 Unauthorized
  • Request dengan token user biasa → Return 403 Forbidden
  • Request dengan token admin → Return 200 OK + token baru
  • Token yang dihasilkan bisa akses endpoint /api/opendk/data
  • Activity log mencatat pembuatan token
  • Service account masih bisa sinkronisasi normal (tidak kena rate limit)

Cakupan Pengujian

Dibuat suite pengujian komprehensif: tests/Feature/ApiTokenEndpointSecurityTest.php

Hasil Tes:

PASS  Tests\Feature\ApiTokenEndpointSecurityTest
  ✓ unauthenticated user cannot access token endpoint
  ✓ regular user cannot access token endpoint
  ✓ token endpoint requires administrator role
  ✓ token endpoint does not have rate limiting
  ✓ security implementation summary

Tests: 5 passed (15 assertions)

Dampak

Sebelum Perbaikan

  • Siapa saja bisa memanggil /api/v1/token dan mendapat token API valid
  • Tidak perlu autentikasi
  • Tidak ada pengecekan otorisasi
  • Bypass akses API lengkap

Setelah Perbaikan

  • Memerlukan token Sanctum valid (auth:sanctum)
  • Memerlukan role administrator (role:administrator)
  • Semua pembuatan token dicatat di log
  • Token lama dicabut saat token baru dibuat
  • Tidak ada rate limiting (service account butuh fleksibilitas)

Issue Terkait

Perubahan Breaking

⚠️ Penting: Perubahan ini mempengaruhi integrasi yang ada:

  1. Service accounts sekarang harus diakses oleh user administrator
  2. Pemanggilan langsung ke /api/v1/token akan gagal dengan 401/403
  3. Token yang ada akan tetap berfungsi sampai dicabut

Panduan Migrasi

Jika Anda punya script sinkronisasi yang ada:

Sebelum:

# Ini TIDAK AKAN BERFUNGSI lagi
curl https://your-domain.com/api/v1/token

Sesudah:

# Harus autentikasi sebagai administrator dulu
curl -H "Authorization: Bearer ADMIN_TOKEN" \
     https://your-domain.com/api/v1/token

File yang Diubah

  1. routes/apiv1.php - Menambahkan middleware role:administrator
  2. app/Http/Controllers/Api/Auth/AuthController.php - Meningkatkan method token()
  3. tests/Feature/ApiTokenEndpointSecurityTest.php - Suite pengujian baru

Pengujian

Jalankan suite pengujian:

php artisan test --filter ApiTokenEndpointSecurityTest

Pengujian manual:

# Tes 1: Harus return 401 (tanpa auth)
curl https://your-domain.com/api/v1/token
# Expected: 401 Unauthorized

# Tes 2: Harus return 403 (user biasa)
curl -H "Authorization: Bearer REGULAR_USER_TOKEN" \
     https://your-domain.com/api/v1/token
# Expected: 403 Forbidden

# Tes 3: Harus return 200 (admin)
curl -H "Authorization: Bearer ADMIN_TOKEN" \
     https://your-domain.com/api/v1/token
# Expected: 200 OK dengan access_token

Audit Keamanan

Perbaikan ini mengatasi:

  • ✅ Kerentanan bypass autentikasi
  • ✅ Pengecekan otorisasi hilang
  • ✅ Tidak ada logging audit
  • ✅ Manajemen lifecycle token

Rekomendasi

  1. Deploy secepatnya - Ini perbaikan keamanan kritis
  2. Monitor log - Cek upaya pembuatan token yang mencurigakan
  3. Rotasi token - Cabut semua token synchronize yang ada setelah deployment
  4. Update dokumentasi - Beritahu tim integrasi tentang perubahan ini

Catatan

  • Tidak ada rate limiting ditambahkan (service account butuh fleksibilitas untuk sinkronisasi)
  • Logging aktivitas diaktifkan untuk audit keamanan
  • Pencabutan token memastikan hanya ada satu token valid pada satu waktu
  • Kompatibel dengan workflow sinkronisasi OpenDK yang ada

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant