atlet99/dtorrent_tracker_v2

[FEATURE] - Add request parameter validation;

Aperta

#12 aperta il 3 nov 2025

 (0 commenti) (0 reazioni) (0 assegnatari)Dart (0 fork)auto 404
enhancementhelp wanted

Metriche repository

Star
 (0 stelle)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

Description

There is no validation of input parameters before sending tracker requests. Invalid parameters (e.g., out-of-range ports, incorrect data lengths) can be sent to trackers, leading to errors or unexpected behavior.

Location

Files:

  • lib/src/tracker/http_tracker.dart (method: generateQueryParameters)
  • lib/src/tracker/udp_tracker.dart (method: generateSecondTouchMessage)
  • lib/src/tracker/tracker.dart (constructor validation)

Current Code

Parameters are used directly without validation:

// HTTP tracker - no validation
params['port'] = options['port'].toString();
params['numwant'] = options['numwant'].toString();

// UDP tracker - no validation
list.addAll(num2Uint32List(options['numwant']));
list.addAll(num2Uint16List(options['port']));

Expected Behavior

Validate all input parameters according to BEP specifications:

  1. port: Must be in range 1-65535
  2. numwant: Should be positive integer, BEP recommends maximum 50
  3. info_hash: Must be exactly 20 bytes
  4. peer_id: Must be exactly 20 bytes (if provided as binary)
  5. compact: Should be 0 or 1
  6. downloaded, uploaded, left: Should be non-negative integers

Invalid parameters should throw clear, descriptive exceptions.

Proposed Implementation

Constructor Validation

Tracker(this.id, this.announceUrl, this.infoHashBuffer, {this.provider}) {
  // Validate info_hash length
  if (infoHashBuffer.length != 20) {
    throw ArgumentError.value(
      infoHashBuffer.length,
      'infoHashBuffer',
      'Info hash must be exactly 20 bytes',
    );
  }
}

HTTP Tracker Validation

@override
Map<String, String> generateQueryParameters(Map<String, dynamic> options) {
  // Validate port
  var port = options['port'] as int?;
  if (port == null || port < 1 || port > 65535) {
    throw ArgumentError.value(
      port,
      'port',
      'Port must be in range 1-65535',
    );
  }
  
  // Validate numwant
  var numwant = options['numwant'] as int? ?? 50;
  if (numwant < 0 || numwant > 50) {
    throw ArgumentError.value(
      numwant,
      'numwant',
      'numwant must be between 0 and 50 (BEP recommendation)',
    );
  }
  
  // Validate peer_id length if provided as binary
  var peerId = options['peerId'];
  if (peerId is Uint8List && peerId.length != 20) {
    throw ArgumentError.value(
      peerId.length,
      'peerId',
      'Peer ID must be exactly 20 bytes',
    );
  }
  
  // Validate downloaded/uploaded/left are non-negative
  var downloaded = options['downloaded'] as int? ?? 0;
  var uploaded = options['uploaded'] as int? ?? 0;
  var left = options['left'] as int? ?? 0;
  
  if (downloaded < 0 || uploaded < 0 || left < 0) {
    throw ArgumentError(
      'downloaded, uploaded, and left must be non-negative integers',
    );
  }
  
  // ... rest of implementation ...
}

UDP Tracker Validation

Similar validation in generateSecondTouchMessage:

@override
Uint8List generateSecondTouchMessage(Uint8List connectionId, Map options) {
  // Validate port
  var port = options['port'] as int?;
  if (port == null || port < 1 || port > 65535) {
    throw ArgumentError.value(port, 'port', 'Port must be in range 1-65535');
  }
  
  // Validate numwant
  var numwant = options['numwant'] as int? ?? 50;
  if (numwant < 0 || numwant > 50) {
    throw ArgumentError.value(numwant, 'numwant', 'numwant must be 0-50');
  }
  
  // Validate peer_id length
  var peerId = options['peerId'];
  if (peerId is String && peerId.length != 20) {
    throw ArgumentError.value(peerId.length, 'peerId', 'Peer ID must be 20 bytes');
  }
  
  // ... rest of implementation ...
}

Impact

  • Severity: Medium (Quality Improvement)
  • Affected: All tracker requests
  • Benefits:
    • Prevents sending invalid requests to trackers
    • Clear error messages for debugging
    • Better compliance with BEP specifications
    • Catches errors early (fail-fast principle)

Additional Context

Parameter validation should happen:

  • Early (in constructors/methods that accept parameters)
  • With clear error messages
  • According to BEP specifications
  • Without breaking backward compatibility (use sensible defaults)

Related Standards

Guida contributor