T09 · Insecure Skill Coding Practices
Error
- Location
- media_server_flask.py:35
- Finding
- Public Unauthenticated Media Enumeration and Download<![CDATA[ ## Vulnerability Details **File Location**: `media_server_flask.py:35, 45-77, 90-178, 406-423`; `media_frp_util.py:180-194` **Vulnerability Type**: Missing authentication and automatic public service exposure **Risk Level**: High ### Vulnerable Code ```python app = Flask(__name__, template_folder='templates') socketio = SocketIO(app) ``` ```python @app.route('/api/list_files', methods=['POST']) def handle_api_list_files(): """WhatsApp API endpoint — returns a playlist of WebRTC player URLs.""" try: frp_domain = get_domain() media_files = get_media_files() if isinstance(media_files, list) and len(media_files) > 0: for media_file in media_files: media_file_name = os.path.basename(media_file) media_file_url = f"http://{frp_domain}/{media_file_name}" ``` ```python @socketio.on('connect') def handle_connect(): sid = request.sid pc = RTCPeerConnection(configuration) with pc_lock: peer_connections[sid] = pc @pc.on("datachannel") def on_datachannel(channel): @channel.on("message") def on_message(message): if isinstance(message, str) and message.startswith("request:"): filename = os.path.basename(message.split(":", 1)[1]) media_dir = os.path.realpath(get_media_directory()) filepath = os.path.realpath(os.path.join(media_dir, filename)) if not filename or not filepath.startswith(media_dir + os.sep): channel.send(json.dumps({"error": "forbidden"})) return if not os.path.isfile(filepath): channel.send(json.dumps({"error": "file not found"})) return async def stream_file_async(): async with aiofiles.open(filepath, "rb") as f: while True: chunk = await f.read(16 * 1024) ...[truncated 2312 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require authentication for every HTTP route and Socket.IO connection. 2. Generate short-lived, cryptographically random, file-scoped capability tokens. 3. Validate authorization again when processing each data-channel file request. 4. Reject Socket.IO connections that do not present a valid authenticated session. 5. Make public FRP tunneling disabled by default and require explicit user opt-in. 6. Bind the service to `127.0.0.1` unless LAN exposure is explicitly enabled. 7. Add per-client request, connection, bandwidth, and concurrency limits. 8. Expire public links and support immediate token revocation. 9. Do not treat the generated UUID hostname or an MD5 checksum as authentication. ]]>
