# Bypass Otorisasi Symfony PATH_INFO: GHSA-3rg7-wf37-54rm

> Kerentanan Symfony HTTP Foundation memungkinkan bypass otorisasi melalui penguraian PATH_INFO yang salah.

**URL:** https://www.ciptadusa.com/blog/symfony-path-info-authorization-bypass  
**Type:** blog  
**Author:** PT Cipta Dua Saudara  
**Category:** Keamanan Aplikasi  
**Published:** 2026-05-30  
**Cover:** https://www.ciptadusa.com/media/defaults/blog-cover.svg  

## Article

# Bypass Otorisasi Symfony PATH_INFO: GHSA-3rg7-wf37-54rm

## Ringkasan

Kerentanan keamanan ditemukan di komponen HTTP Foundation Symfony yang memungkinkan otorisasi terbatas melewati penguraian PATH_INFO yang salah. Dilacak sebagai GHSA-3rg7-wf37-54rm, kerentanan ini mempengaruhi beberapa versi Symfony dan dapat menyebabkan pengelakan kontrol keamanan.

## Detail teknis

### Deskripsi Kerentanan

Kerentanan ada pada cara komponen HttpFoundation Symfony mem-parse variabel server `PATH_INFO`. Penguraian yang salah dapat menyebabkan perbedaan antara jalur yang digunakan untuk keputusan otorisasi dan jalur sebenarnya yang sedang diakses.

### Root cause

Proses penanganan permintaan Symfony `PATH_INFO` untuk perutean dan otorisasi. Ketika jalur diurai secara berbeda oleh berbagai komponen aplikasi, penyerang dapat mengeksploitasi ketidakkonsistenan ini untuk melewati kontrol akses.

### Versi yang Terkena Dampak

- Symfony 5.x (diperbaiki di 5.4.50)
- Symfony 6.x (diperbaiki pada 6.4.29)
- Symfony 7.x (diperbaiki di 7.3.7)

### Mekanisme Serangan

```php
// Simplified attack scenario
// Authorization middleware sees:
// PATH_INFO = "/admin/dashboard"
// Grants access based on this path

// But the actual request reaches:
// PATH_INFO = "/admin/dashboard/../../../public/resource"
// Accessing restricted resource through path traversal
```

## Eksploitasi

### Skenario Serangan

1. **Permintaan Kerajinan**: Penyerang membuat permintaan dengan format PATH_INFO khusus
2. **Pemeriksaan Otorisasi**: Middleware mengevaluasi jalur asli
3. **Resolusi Perutean**: Aplikasi memutuskan ke jalur yang berbeda
4. **Akses Diberikan**: Penyerang mengakses sumber daya yang dibatasi

### Contoh Serangan

```http
GET /admin/dashboard HTTP/1.1
Host: vulnerable-app.com
# Path is normalized differently at authorization vs. routing
```

## Dampak

### Tingkat Keparahan: Sedang

- **Kerahasiaan**: Sedang - Akses ke sumber daya terbatas
- **Integritas**: Rendah - Potensi modifikasi terbatas
- **Ketersediaan**: Tidak ada

### Dampak Bisnis

- Akses tidak sah ke panel admin
- Paparan data
- Pelanggaran kepatuhan

## Mitigasi

### Langkah cepat

1. **Perbarui Symfony** ke versi yang dipatch:
   - Symfony 5.4.50 atau lebih baru
   - Symfony 6.4.29 atau lebih baru
   - Symfony 7.3.7 atau lebih baru

2. **Tinjau Logika Otorisasi**:
   ```php
   // Check current implementation
   // Ensure authorization happens at the correct layer
   ```

### Pertahanan Secara Mendalam

```php
// Secure authorization implementation
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class SecureAuthorizationMiddleware
{
    private $authorizationChecker;
    
    public function __construct(AuthorizationCheckerInterface $authorizationChecker)
    {
        $this->authorizationChecker = $authorizationChecker;
    }
    
    public function handle(Request $request, callable $next)
    {
        // Get the resolved path, not the raw PATH_INFO
        $path = $request->getPathInfo();
        
        // Normalize the path
        $path = $this->normalizePath($path);
        
        // Perform authorization check
        if (!$this->isPathAllowed($path)) {
            throw new AccessDeniedException('Access denied');
        }
        
        return $next($request);
    }
    
    private function normalizePath(string $path): string
    {
        // Remove path traversal attempts
        $path = str_replace(['../', '..\\'], '', $path);
        // Normalize slashes
        $path = preg_replace('#/+#', '/', $path);
        // Remove trailing slash
        $path = rtrim($path, '/');
        
        return $path;
    }
    
    private function isPathAllowed(string $path): bool
    {
        // Implement your authorization logic
        return $this->authorizationChecker->isGranted('ACCESS', $path);
    }
}
```

### Konfigurasi Perutean

```php
// config/routes.yaml
controllers:
    resource: ../src/Controller/
    type: attribute
    # Ensure consistent path handling
    trailing_slash_on_root: false
```

## Masalah Keamanan Symfony Terkait

### Kerentanan HTTP Foundation Lainnya

Symfony telah mengatasi beberapa masalah keamanan terkait:

1. **Penyelundupan Permintaan**: Penguraian permintaan tidak konsisten
2. **Injeksi Header**: Penanganan nilai header yang tidak tepat
3. **Session Fixation**: Masalah regenerasi ID Sesi

### Praktik Terbaik Keamanan

```php
// Symfony security configuration
// config/packages/security.yaml
security:
    access_control:
        # Use explicit paths, not patterns
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/api/private, roles: ROLE_API }
        
    # Enable security firewalls
    firewalls:
        main:
            # Configure authentication
            pattern: ^/
            form_login: true
            logout: true
```

## Fitur Keamanan Symfony

### Perlindungan Bawaan

```php
// Use Symfony's security component
use Symfony\Component\Security\Core\Security;

class SecureController extends AbstractController
{
    #[IsGranted('ROLE_ADMIN')]
    public function adminDashboard(): Response
    {
        // Only accessible to admins
        return $this->render('admin/dashboard.html.twig');
    }
    
    #[IsGranted('POST_EDIT', subject: 'post')]
    public function editPost(Post $post): Response
    {
        // Only accessible if user can edit this specific post
        return $this->render('post/edit.html.twig', ['post' => $post]);
    }
}
```

### Kontrol Akses Berbasis Jalur

```php
// Custom voter for path-based authorization
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class PathVoter extends Voter
{
    protected function supports(string $attribute, mixed $subject): bool
    {
        return $attribute === 'PATH_ACCESS';
    }
    
    protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
    {
        $path = $subject;
        $user = $token->getUser();
        
        // Implement path-based authorization logic
        return $this->isPathAllowedForUser($path, $user);
    }
    
    private function isPathAllowedForUser(string $path, UserInterface $user): bool
    {
        // Define allowed paths for each role
        $allowedPaths = [
            'ROLE_ADMIN' => ['/admin'],
            'ROLE_USER' => ['/dashboard', '/profile'],
        ];
        
        foreach ($user->getRoles() as $role) {
            if (isset($allowedPaths[$role])) {
                foreach ($allowedPaths[$role] as $allowedPath) {
                    if (str_starts_with($path, $allowedPath)) {
                        return true;
                    }
                }
            }
        }
        
        return false;
    }
}
```

## Monitoring dan Deteksi

### Peristiwa Otorisasi Logging

```php
// Monitor authorization attempts
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Event\AuthorizationEvent;

class AuthorizationLogger implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            AuthorizationEvent::class => 'onAuthorization',
        ];
    }
    
    public function onAuthorization(AuthorizationEvent $event): void
    {
        $request = $event->getRequest();
        $path = $request->getPathInfo();
        $user = $event->getToken()->getUser();
        
        // Log authorization decisions
        $this->logger->info('Authorization check', [
            'path' => $path,
            'user' => $user->getUserIdentifier(),
            'granted' => $event->isGranted(),
        ]);
    }
}
```

## Praktik Terbaik untuk Keamanan Symfony

### Penanganan Jalur

1. **Normalisasi jalur lebih awal**: Hapus upaya traversal
2. **Gunakan router Symfony**: Jangan menguraikan jalur secara manual
3. **Validasi masukan**: Sanitasi semua komponen jalur yang disediakan pengguna

### Lapisan Otorisasi

1. **Gunakan pemilih**: Terapkan otorisasi yang terperinci
2. **Terapkan di tingkat pengontrol**: Gunakan anotasi/atribut
3. **Uji secara menyeluruh**: Sertakan manipulasi jalur dalam kasus pengujian

## Penutup

GHSA-3rg7-wf37-54rm menyoroti pentingnya penanganan jalur yang konsisten dalam aplikasi web. Dengan memperbarui Symfony dan menerapkan normalisasi jalur yang tepat, developer dapat mencegah kerentanan bypass otorisasi.

## Referensi

- [Advisory Keamanan Symfony GHSA-3rg7-wf37-54rm](https://github.com/symfony/symfony/security/advisories/GHSA-3rg7-wf37-54rm)
- [Dokumentasi Keamanan Symfony](https://symfony.com/doc/current/security.html)
- [Komponen Symfony HttpFoundation](https://symfony.com/doc/current/components/http_foundation.html)

---

*Markdown version of https://www.ciptadusa.com/blog/symfony-path-info-authorization-bypass — generated for AI agents and LLM crawlers.*
