mirror of
https://github.com/smittix/intercept.git
synced 2026-07-18 06:18:11 -07:00
Add security hardening and bias-t support
Security improvements: - Add interface name validation to prevent command injection - Fix XSS vulnerability in pager message display - Add security headers (X-Content-Type-Options, X-Frame-Options, etc.) - Disable Werkzeug debug PIN - Add security documentation Features: - Add bias-t power support for SDR dongles across all modes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -381,9 +381,11 @@ def start_adsb():
|
||||
builder = SDRFactory.get_builder(sdr_type)
|
||||
|
||||
# Build ADS-B decoder command
|
||||
bias_t = data.get('bias_t', False)
|
||||
cmd = builder.build_adsb_command(
|
||||
device=sdr_device,
|
||||
gain=float(gain)
|
||||
gain=float(gain),
|
||||
bias_t=bias_t
|
||||
)
|
||||
|
||||
# For RTL-SDR, ensure we use the found dump1090 path
|
||||
|
||||
+13
-2
@@ -21,6 +21,7 @@ import app as app_module
|
||||
from utils.dependencies import check_tool
|
||||
from utils.logging import bluetooth_logger as logger
|
||||
from utils.sse import format_sse
|
||||
from utils.validation import validate_bluetooth_interface
|
||||
from data.oui import OUI_DATABASE, load_oui_database, get_manufacturer
|
||||
from data.patterns import AIRTAG_PREFIXES, TILE_PREFIXES, SAMSUNG_TRACKER
|
||||
from utils.constants import (
|
||||
@@ -304,9 +305,14 @@ def start_bt_scan():
|
||||
|
||||
data = request.json
|
||||
scan_mode = data.get('mode', 'hcitool')
|
||||
interface = data.get('interface', 'hci0')
|
||||
scan_ble = data.get('scan_ble', True)
|
||||
|
||||
# Validate Bluetooth interface name
|
||||
try:
|
||||
interface = validate_bluetooth_interface(data.get('interface', 'hci0'))
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
app_module.bt_interface = interface
|
||||
app_module.bt_devices = {}
|
||||
|
||||
@@ -388,7 +394,12 @@ def stop_bt_scan():
|
||||
def reset_bt_adapter():
|
||||
"""Reset Bluetooth adapter."""
|
||||
data = request.json
|
||||
interface = data.get('interface', 'hci0')
|
||||
|
||||
# Validate Bluetooth interface name
|
||||
try:
|
||||
interface = validate_bluetooth_interface(data.get('interface', 'hci0'))
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
with app_module.bt_lock:
|
||||
if app_module.bt_process:
|
||||
|
||||
@@ -54,6 +54,7 @@ scanner_config = {
|
||||
'scan_delay': 0.1, # Seconds between frequency hops (keep low for fast scanning)
|
||||
'device': 0,
|
||||
'gain': 40,
|
||||
'bias_t': False, # Bias-T power for external LNA
|
||||
}
|
||||
|
||||
# Activity log
|
||||
@@ -177,6 +178,9 @@ def scanner_loop():
|
||||
'-g', str(scanner_config['gain']),
|
||||
'-d', str(scanner_config['device']),
|
||||
]
|
||||
# Add bias-t flag if enabled (for external LNA power)
|
||||
if scanner_config.get('bias_t', False):
|
||||
rtl_cmd.append('-T')
|
||||
|
||||
try:
|
||||
# Start rtl_fm
|
||||
@@ -365,6 +369,9 @@ def _start_audio_stream(frequency: float, modulation: str):
|
||||
'-d', str(scanner_config['device']),
|
||||
'-l', str(scanner_config['squelch']),
|
||||
]
|
||||
# Add bias-t flag if enabled (for external LNA power)
|
||||
if scanner_config.get('bias_t', False):
|
||||
rtl_cmd.append('-T')
|
||||
|
||||
encoder_cmd = [
|
||||
ffmpeg_path,
|
||||
@@ -497,6 +504,7 @@ def start_scanner() -> Response:
|
||||
scanner_config['scan_delay'] = float(data.get('scan_delay', 0.5))
|
||||
scanner_config['device'] = int(data.get('device', 0))
|
||||
scanner_config['gain'] = int(data.get('gain', 40))
|
||||
scanner_config['bias_t'] = bool(data.get('bias_t', False))
|
||||
except (ValueError, TypeError) as e:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
|
||||
+3
-1
@@ -233,6 +233,7 @@ def start_decoding() -> Response:
|
||||
builder = SDRFactory.get_builder(sdr_device.sdr_type)
|
||||
|
||||
# Build FM demodulation command
|
||||
bias_t = data.get('bias_t', False)
|
||||
rtl_cmd = builder.build_fm_demod_command(
|
||||
device=sdr_device,
|
||||
frequency_mhz=freq,
|
||||
@@ -240,7 +241,8 @@ def start_decoding() -> Response:
|
||||
gain=float(gain) if gain and gain != '0' else None,
|
||||
ppm=int(ppm) if ppm and ppm != '0' else None,
|
||||
modulation='fm',
|
||||
squelch=squelch if squelch and squelch != 0 else None
|
||||
squelch=squelch if squelch and squelch != 0 else None,
|
||||
bias_t=bias_t
|
||||
)
|
||||
|
||||
multimon_cmd = ['multimon-ng', '-t', 'raw'] + decoders + ['-f', 'alpha', '-']
|
||||
|
||||
+3
-1
@@ -114,11 +114,13 @@ def start_sensor() -> Response:
|
||||
builder = SDRFactory.get_builder(sdr_device.sdr_type)
|
||||
|
||||
# Build ISM band decoder command
|
||||
bias_t = data.get('bias_t', False)
|
||||
cmd = builder.build_ism_command(
|
||||
device=sdr_device,
|
||||
frequency_mhz=freq,
|
||||
gain=float(gain) if gain and gain != 0 else None,
|
||||
ppm=int(ppm) if ppm and ppm != 0 else None
|
||||
ppm=int(ppm) if ppm and ppm != 0 else None,
|
||||
bias_t=bias_t
|
||||
)
|
||||
|
||||
full_cmd = ' '.join(cmd)
|
||||
|
||||
+46
-8
@@ -19,7 +19,7 @@ import app as app_module
|
||||
from utils.dependencies import check_tool, get_tool_path
|
||||
from utils.logging import wifi_logger as logger
|
||||
from utils.process import is_valid_mac, is_valid_channel
|
||||
from utils.validation import validate_wifi_channel, validate_mac_address
|
||||
from utils.validation import validate_wifi_channel, validate_mac_address, validate_network_interface
|
||||
from utils.sse import format_sse
|
||||
from data.oui import get_manufacturer
|
||||
from utils.constants import (
|
||||
@@ -303,11 +303,13 @@ def get_wifi_interfaces():
|
||||
def toggle_monitor_mode():
|
||||
"""Enable or disable monitor mode on an interface."""
|
||||
data = request.json
|
||||
interface = data.get('interface')
|
||||
action = data.get('action', 'start')
|
||||
|
||||
if not interface:
|
||||
return jsonify({'status': 'error', 'message': 'No interface specified'})
|
||||
# Validate interface name to prevent command injection
|
||||
try:
|
||||
interface = validate_network_interface(data.get('interface'))
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
if action == 'start':
|
||||
if check_tool('airmon-ng'):
|
||||
@@ -458,10 +460,19 @@ def start_wifi_scan():
|
||||
return jsonify({'status': 'error', 'message': 'Scan already running'})
|
||||
|
||||
data = request.json
|
||||
interface = data.get('interface') or app_module.wifi_monitor_interface
|
||||
channel = data.get('channel')
|
||||
band = data.get('band', 'abg')
|
||||
|
||||
# Use provided interface or fall back to stored monitor interface
|
||||
interface = data.get('interface')
|
||||
if interface:
|
||||
try:
|
||||
interface = validate_network_interface(interface)
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
else:
|
||||
interface = app_module.wifi_monitor_interface
|
||||
|
||||
if not interface:
|
||||
return jsonify({'status': 'error', 'message': 'No monitor interface available.'})
|
||||
|
||||
@@ -557,7 +568,16 @@ def send_deauth():
|
||||
target_bssid = data.get('bssid')
|
||||
target_client = data.get('client', 'FF:FF:FF:FF:FF:FF')
|
||||
count = data.get('count', 5)
|
||||
interface = data.get('interface') or app_module.wifi_monitor_interface
|
||||
|
||||
# Validate interface
|
||||
interface = data.get('interface')
|
||||
if interface:
|
||||
try:
|
||||
interface = validate_network_interface(interface)
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
else:
|
||||
interface = app_module.wifi_monitor_interface
|
||||
|
||||
if not target_bssid:
|
||||
return jsonify({'status': 'error', 'message': 'Target BSSID required'})
|
||||
@@ -612,7 +632,16 @@ def capture_handshake():
|
||||
data = request.json
|
||||
target_bssid = data.get('bssid')
|
||||
channel = data.get('channel')
|
||||
interface = data.get('interface') or app_module.wifi_monitor_interface
|
||||
|
||||
# Validate interface
|
||||
interface = data.get('interface')
|
||||
if interface:
|
||||
try:
|
||||
interface = validate_network_interface(interface)
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
else:
|
||||
interface = app_module.wifi_monitor_interface
|
||||
|
||||
if not target_bssid or not channel:
|
||||
return jsonify({'status': 'error', 'message': 'BSSID and channel required'})
|
||||
@@ -701,7 +730,16 @@ def capture_pmkid():
|
||||
data = request.json
|
||||
target_bssid = data.get('bssid')
|
||||
channel = data.get('channel')
|
||||
interface = data.get('interface') or app_module.wifi_monitor_interface
|
||||
|
||||
# Validate interface
|
||||
interface = data.get('interface')
|
||||
if interface:
|
||||
try:
|
||||
interface = validate_network_interface(interface)
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
else:
|
||||
interface = app_module.wifi_monitor_interface
|
||||
|
||||
if not target_bssid:
|
||||
return jsonify({'status': 'error', 'message': 'BSSID required'})
|
||||
|
||||
Reference in New Issue
Block a user