Back to skill

Security audit

多源音乐下载

Security checks for vulnerabilities and agentic risk

Overview

This music downloader does what it says, but it disables HTTPS certificate checks broadly and downloads remote-provided files without enough validation or size limits.

Install only if you are comfortable with a downloader that contacts many third-party music sites, bypasses HTTPS certificate validation, and saves remote content to /tmp/music. Prefer a fixed version that keeps TLS verification enabled, validates media URL domains and file types, and enforces a reasonable maximum download size.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
music_downloader.py:15
Finding

TLS Certificate Verification Is Disabled for All Network Requests

Content
View full analysis
List[Dict]: try: url = f"https://www.thttt.com/so.php?wd={quote(keyword)}" resp = self.session.get(url, timeout=15, verify=False) html = resp.text ``` Representative API request: ```python def get_url_thttt(self, hash_code: str) -> Optional[str]: try: url = "https://www.thttt.com/style/js/play.php" resp = self.session.post( url, data={'id': hash_code, 'type': 'dance'}, timeout=15, verify=False ) result = resp.json() ``` The final media download also disables certificate verification: ```python try: resp = self.session.get( url, headers=headers, timeout=60, stream=True, verify=False ) resp.raise_for_status() ``` The same `verify=False` setting appears in every provider integration at lines 37, 65, 75, 93, 103, 121, 131, 151, 158, 168, 189, 196, 210, 223, 232, 246, 258, 271, 282, 298, 313, 326, and 380. ### Technical Analysis The `verify=False` argument instructs Requests not to authenticate the certificate presented by an HTTPS server. Encryption may still be negotiated, but the client cannot establish that it is communicating with the intended provider rather than an impersonating server. Because verification is disabled during both meta ...[truncated 1720 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
music_downloader.py:364
Finding

Untrusted Provider URLs Are Downloaded Without Destination Validation or a Maximum Size

Content
View full analysis
bool: """下载文件""" if 'kuwo.cn' in url: referer = 'https://www.kuwo.cn/' elif 'kugou.com' in url: referer = 'https://www.kugou.com/' elif '163.com' in url or '126.net' in url: referer = 'https://music.163.com/' elif 'qq.com' in url: referer = 'https://y.qq.com/' else: referer = 'https://www.thttt.com/' headers = {"User-Agent": HEADERS["User-Agent"], "Referer": referer} try: resp = self.session.get( url, headers=headers, timeout=60, stream=True, verify=False ) resp.raise_for_status() size = int(resp.headers.get('content-length', 0)) if size < 1024: print(f" ⚠️ 文件太小: {size} bytes") return False os.makedirs(os.path.dirname(save_path), exist_ok=True) with open(save_path, 'wb') as f: for chunk in resp.iter_content(8192): if chunk: f.write(chunk) print(f" ✅ 下载成功: {save_path}") return True except Exception as e: print(f" ❌ 下载失败: {e}") return False ``` Playback URLs obtained from remote provider responses are passed directly to that method: ```python play_url = get_url_funcs[source](song) if not play_url: print(" ⚠️ 无法获取链接") continue safe_name = re.sub(r'[<>:"/\\|?*]', '_', f"{song['artist']}_{song['name']}") save_path = os.path.join(save_dir, f"{safe_name}.mp3") if self.download(play_url, save_path): return save_p ...[truncated 3018 chars]
Remediation
View remediation
MAX_DOWNLOAD_BYTES: raise ValueError("Media file exceeds maximum size") written = 0 with open(save_path, "xb") as output: for chunk in resp.iter_content(8192): if not chunk: continue written += len(chunk) if written > MAX_DOWNLOAD_BYTES: raise ValueError("Media file exceeds maximum size") output.write(chunk) ``` Delete partial output files when validation or downloading fails. 6. Require an expected audio MIME type and validate file magic bytes rather than relying on the `.mp3` extension. 7. Apply execution-environment egress controls so the Skill cannot contact loopback, private, link-local, metadata, or unrelated external destinations. 8. Use randomized, securely created output files where practical, and avoid over ...[truncated 27 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (27)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly downloads MP3 files to /tmp/music/ but does not clearly warn users up front that it writes files to local storage. In an agent setting, undisclosed filesystem writes can surprise users, consume disk space, and create persistence/privacy issues, especially when the content is fetched from multiple untrusted external sources.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The HTTP headers force Accept-Language to zh-CN,zh;q=0.9, which imposes a specific locale preference in the skill's behavior. The file does not provide any opt-in, configuration, or documented justification for restricting requests to Chinese language content.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

Disabling TLS certificate verification allows a man-in-the-middle attacker to intercept or modify traffic to the remote music source. In this skill, untrusted network responses are used to discover media URLs, so tampered responses could redirect downloads to malicious infrastructure or manipulate results silently.

Content

Scanner excerpt · music_downloader.py (reported line 37)May include surrounding context.

python
def search_thttt(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.thttt.com/so.php?wd={quote(keyword)}"
            resp = self.session.get(url, timeout=15, verify=False)
            html = resp.text
            
            songs = []

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This POST request disables TLS verification while retrieving playback metadata from an external source. An attacker positioned on the network could forge the JSON response and supply attacker-controlled media URLs, causing unsafe downloads or user deception.

Content

Scanner excerpt · music_downloader.py (reported line 65)May include surrounding context.

python
def get_url_thttt(self, hash_code: str) -> Optional[str]:
        try:
            url = "https://www.thttt.com/style/js/play.php"
            resp = self.session.post(url, data={'id': hash_code, 'type': 'dance'}, timeout=15, verify=False)
            result = resp.json()
            return result.get('url') if result.get('msg') == 1 else None
        except:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

Certificate validation is disabled for the Kugou search request, making search results vulnerable to interception and tampering. Because these results feed later URL resolution and download decisions, a MITM could influence which resources are fetched.

Content

Scanner excerpt · music_downloader.py (reported line 75)May include surrounding context.

python
def search_kugou(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://complexsearch.kugou.com/v2/search/song?keyword={quote(keyword)}&page=1&pagesize=15"
            resp = self.session.get(url, timeout=15, verify=False)
            data = resp.json()
            songs = []
            for item in data.get('data', {}).get('lists', []):

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This request extracts a play_url from HTML fetched without TLS verification. A network attacker could inject a forged play_url pointing to malicious or unexpected content, leading the downloader to fetch attacker-chosen files.

Content

Scanner excerpt · music_downloader.py (reported line 93)May include surrounding context.

python
def get_url_kugou(self, hash_code: str) -> Optional[str]:
        try:
            url = f"https://www.kugou.com/yy/html/singer.html?hash={hash_code}"
            resp = self.session.get(url, timeout=15, verify=False)
            match = re.search(r'"play_url":"([^"]+)"', resp.text)
            return match.group(1).replace('\\/', '/') if match else None
        except:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The Kuwo search API call disables certificate validation, exposing the search flow to MITM tampering. Since the application trusts remote metadata to drive subsequent requests, this weakens the entire download chain.

Content

Scanner excerpt · music_downloader.py (reported line 103)May include surrounding context.

python
def search_kuwo(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={quote(keyword)}&pn=1&rn=15"
            resp = self.session.get(url, headers={"Referer": "https://www.kuwo.cn"}, timeout=15, verify=False)
            data = resp.json()
            songs = []
            for item in data.get('data', {}).get('list', []):

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

Playback information is requested over HTTPS with verification disabled, allowing an attacker to alter the returned media URL. In a downloader, this is especially risky because the next step is fetching and writing the referenced content to disk.

Content

Scanner excerpt · music_downloader.py (reported line 121)May include surrounding context.

python
def get_url_kuwo(self, rid: str) -> Optional[str]:
        try:
            url = f"https://www.kuwo.cn/api/v1/www/music/playInfo?mid={rid}&type=music&httpsStatus=1"
            resp = self.session.get(url, timeout=15, verify=False)
            return resp.json().get('data', {}).get('url', '')
        except:
            return None

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

Disabling TLS verification for NetEase search makes the metadata channel untrusted even though HTTPS is used. A MITM attacker could manipulate search results and steer the tool toward malicious or unrelated content.

Content

Scanner excerpt · music_downloader.py (reported line 131)May include surrounding context.

python
try:
            url = f"https://music.163.com/api/search/get?s={quote(keyword)}&type=1&offset=0&limit=15"
            headers = {"Referer": "https://music.163.com"}
            resp = self.session.get(url, headers=headers, timeout=15, verify=False)
            data = resp.json()
            songs = []
            for item in data.get('result', {}).get('songs', []):

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This redirect-probing request trusts an HTTPS response without validating the certificate, so a MITM could forge the redirect target. Since the code treats the Location header as a download URL candidate, this can directly influence what content is later retrieved.

Content

Scanner excerpt · music_downloader.py (reported line 151)May include surrounding context.

python
try:
            # 方法1: 直链
            url = f"https://music.163.com/song/media/outer/url?id={song_id}"
            resp = self.session.get(url, timeout=15, verify=False, allow_redirects=False)
            if resp.status_code == 302:
                loc = resp.headers.get('Location', '')
                if 'music.126.net' in loc:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The player URL API response is fetched with TLS verification disabled, so an attacker could substitute arbitrary media URLs in the JSON payload. That enables silent redirection of downloads and undermines the authenticity of retrieved files.

Content

Scanner excerpt · music_downloader.py (reported line 158)May include surrounding context.

python
return loc
            # 方法2: 通过详情API
            url = f"https://music.163.com/api/song/enhance/player/url?ids=[{song_id}]&br=320000"
            resp = self.session.get(url, headers={"Referer": "https://music.163.com"}, timeout=15, verify=False)
            data = resp.json()
            return data.get('data', [{}])[0].get('url', '')
        except:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

QQ search results are requested with verify=False, allowing network interception and response tampering. Because those results determine later requests and downloads, the impact extends beyond incorrect search output to potentially malicious file retrieval.

Content

Scanner excerpt · music_downloader.py (reported line 168)May include surrounding context.

python
def search_qq(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://c.y.qq.com/soso/fcgi-bin/client_search_cp?p=1&n=15&w={quote(keyword)}&format=json"
            resp = self.session.get(url, timeout=15, verify=False)
            data = resp.json()
            songs = []
            for item in data.get('data', {}).get('song', {}).get('list', []):

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This page fetch disables TLS verification before scraping an audio URL from the response. A MITM attacker could inject a crafted URL into the HTML, causing the program to fetch attacker-controlled media content.

Content

Scanner excerpt · music_downloader.py (reported line 189)May include surrounding context.

python
# QQ音乐需要特殊签名,这里使用简化方案
            # 通过搜索页面的播放链接
            url = f"https://y.qq.com/n/ryqq/songDetail/{songmid}"
            resp = self.session.get(url, timeout=15, verify=False)
            # 尝试提取音频链接
            match = re.search(r'"url":"(https?://[^"]+\.m4a[^"]*)"', resp.text)
            if match:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The fallback QQ API request uses HTTPS without certificate validation, making the returned purl/sip values untrustworthy. Since these values are concatenated into a final download URL, tampering can directly redirect the downloader to malicious content.

Content

Scanner excerpt · music_downloader.py (reported line 196)May include surrounding context.

python
return match.group(1).replace('\\/', '/')
            # 备用方案:使用ws关联接口
            url = f"https://u.y.qq.com/cgi-bin/musicu.fcg?data={quote(json.dumps({'req': {'module': 'CDN.SrfCdnDispatchServer', 'method': 'GetCdnDispatch', 'param': {'guid': '1234567890', 'calltype': 0, 'userip': ''}}, 'req_0': {'module': 'vkey.GetVkeyServer', 'method': 'CgiGetVkey', 'param': {'guid': '1234567890', 'songmid': [songmid], 'songtype': [0], 'uin': '0', 'loginflag': 1, 'platform': '20'}}}, ensure_ascii=False))}"
            resp = self.session.get(url, timeout=15, verify=False)
            data = resp.json()
            purl = data.get('req_0', {}).get('data', {}).get('midurlinfo', [{}])[0].get('purl', '')
            sip = data.get('req', {}).get('data', {}).get('sip', [''])[0]

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The Gequbao search request disables TLS verification, enabling MITM manipulation of returned song IDs and metadata. In this tool, compromised metadata can cascade into unsafe URL retrieval and downloads.

Content

Scanner excerpt · music_downloader.py (reported line 210)May include surrounding context.

python
def search_gequbao(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.gequbao.com/s/{quote(keyword)}"
            resp = self.session.get(url, timeout=15, verify=False)
            songs = []
            pattern = r'data-id="(\d+)"[^>]*data-name="([^"]*)"[^>]*data-singer="([^"]*)"'
            for song_id, name, singer in re.findall(pattern, resp.text)[:15]:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This API call fetches a direct song URL over HTTPS with certificate checks disabled. An attacker on the network could replace the URL with arbitrary content sources, resulting in unauthorized or malicious downloads.

Content

Scanner excerpt · music_downloader.py (reported line 223)May include surrounding context.

python
def get_url_gequbao(self, song_id: str) -> Optional[str]:
        try:
            url = f"https://www.gequbao.com/api/song/url?id={song_id}"
            resp = self.session.get(url, timeout=15, verify=False)
            return resp.json().get('url', '')
        except:
            return None

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

TLS verification is disabled for 5nd search, so a network attacker can tamper with the HTML and influence which song IDs are processed. That compromises trust in the entire workflow because subsequent steps depend on these identifiers.

Content

Scanner excerpt · music_downloader.py (reported line 232)May include surrounding context.

python
def search_5nd(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.5nd.com/song/0-0-0-0-0-0-0-0-1-0-0-0.html?searchKey={quote(keyword)}"
            resp = self.session.get(url, timeout=15, verify=False)
            songs = []
            # 提取歌曲链接
            pattern = r'href="/song/(\d+)\.htm"[^>]*>([^<]+)</a>'

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This page fetch extracts an MP3 link from unverified HTTPS content. A MITM attacker could inject or alter that link, making the downloader retrieve malicious or unintended files.

Content

Scanner excerpt · music_downloader.py (reported line 246)May include surrounding context.

python
def get_url_5nd(self, song_id: str) -> Optional[str]:
        try:
            url = f"https://www.5nd.com/song/{song_id}.htm"
            resp = self.session.get(url, timeout=15, verify=False)
            # 提取播放链接
            match = re.search(r'href="(https?://[^"]+\.mp3[^"]*)"', resp.text)
            if match:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The 1ting search request uses verify=False, which defeats HTTPS authenticity and permits response tampering. Since parsed results feed later media retrieval, this can indirectly lead to attacker-chosen downloads.

Content

Scanner excerpt · music_downloader.py (reported line 258)May include surrounding context.

python
def search_1ting(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.1ting.com/search?q={quote(keyword)}"
            resp = self.session.get(url, timeout=15, verify=False)
            songs = []
            pattern = r'href="/song/(\d+)"[^>]*>([^<]+)</a>'
            for sid, name in re.findall(pattern, resp.text)[:15]:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

Disabling TLS verification while scraping MP3 URLs from a song page allows a MITM to inject arbitrary links into the response. The downloader would then trust and fetch those links, writing the result to disk.

Content

Scanner excerpt · music_downloader.py (reported line 271)May include surrounding context.

python
def get_url_1ting(self, song_id: str) -> Optional[str]:
        try:
            url = f"https://www.1ting.com/song/{song_id}"
            resp = self.session.get(url, timeout=15, verify=False)
            match = re.search(r'href="(https?://[^"]+\.mp3[^"]*)"', resp.text)
            if match:
                return match.group(1)

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The 9ku search response is fetched without certificate verification, allowing attackers to alter song listings and identifiers. In a multi-source downloader, this broad trust in unauthenticated metadata increases the chance of malicious redirection.

Content

Scanner excerpt · music_downloader.py (reported line 282)May include surrounding context.

python
def search_9ku(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.9ku.com/soso/-k-{quote(keyword)}-k-.htm"
            resp = self.session.get(url, timeout=15, verify=False)
            songs = []
            # 解析歌曲列表
            pattern = r'href="/[a-z]+/(\d+)\.htm"[^>]*title="([^"]+)"'

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This request parses playback/download URLs from HTML received over HTTPS with verification disabled. A network attacker could inject malicious URLs, leading directly to download of attacker-controlled files.

Content

Scanner excerpt · music_downloader.py (reported line 298)May include surrounding context.

python
def get_url_9ku(self, song_id: str) -> Optional[str]:
        try:
            url = f"https://www.9ku.com/play/{song_id}.htm"
            resp = self.session.get(url, timeout=15, verify=False)
            match = re.search(r'href="(https?://[^"]+\.mp3[^"]*)"', resp.text)
            if match:
                return match.group(1)

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The MusicEnc search request disables TLS certificate verification, which allows tampering with search results and IDs. Because those IDs drive later URL resolution, the weakness can influence what content is ultimately downloaded.

Content

Scanner excerpt · music_downloader.py (reported line 313)May include surrounding context.

python
def search_musicenc(self, keyword: str) -> List[Dict]:
        try:
            url = f"https://www.musicenc.com/search/{quote(keyword)}.html"
            resp = self.session.get(url, timeout=15, verify=False)
            songs = []
            pattern = r'href="/song/(\d+)\.html"[^>]*>([^<]+)</a>'
            for sid, name in re.findall(pattern, resp.text)[:15]:

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

This page scrape uses unverified HTTPS before extracting MP3 links, so a MITM attacker can replace the media URL with an arbitrary endpoint. That is dangerous because the tool proceeds to fetch and save the referenced content.

Content

Scanner excerpt · music_downloader.py (reported line 326)May include surrounding context.

python
def get_url_musicenc(self, song_id: str) -> Optional[str]:
        try:
            url = f"https://www.musicenc.com/song/{song_id}.html"
            resp = self.session.get(url, timeout=15, verify=False)
            match = re.search(r'href="(https?://[^"]+\.mp3[^"]*)"', resp.text)
            if match:
                return match.group(1)

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The final download request itself disables TLS verification, which is the most direct risk in this file. Even if earlier discovery steps were trustworthy, a MITM attacker could tamper with the actual file transfer and cause corrupted or malicious content to be written to disk without detection.

Content

Scanner excerpt · music_downloader.py (reported line 380)May include surrounding context.

python
headers = {"User-Agent": HEADERS["User-Agent"], "Referer": referer}
        
        try:
            resp = self.session.get(url, headers=headers, timeout=60, stream=True, verify=False)
            resp.raise_for_status()
            
            size = int(resp.headers.get('content-length', 0))

Static analysis

No suspicious patterns detected.