T09 · Insecure Skill Coding Practices
- Location
sentiment_analyzer.py:57- Finding
Untrusted Social-Media Content Can Manipulate AI-Generated Trading Signals
- Content
View full analysis
Vulnerability Details
File Location:
sentiment_analyzer.py, lines 57-89 and 127-150
Vulnerability Type: Indirect prompt injection and insufficient validation of LLM output
Risk Level: MediumVulnerable Code
python prompt = f"""分析以下加密货币相关新闻的情绪,只返回 JSON: {{ "sentiment": "bullish" 或 "bearish" 或 "neutral", "score": 0-1 之间的数字, "confidence": 0-1 之间的数字, "keywords": ["关键词 1", "关键词 2"] }} 新闻内容:{text[:500]}""" data = json.dumps({ "model": "qwen-turbo", "input": {"messages": [{"role": "user", "content": prompt}]}, "parameters": {"temperature": 0.1} }).encode('utf-8') req = urllib.request.Request( DASHSCOPE_API, data=data, headers={ "Authorization": f"Bearer {DASHSCOPE_KEY}", "Content-Type": "application/json" } ) try: with urllib.request.urlopen(req, timeout=10) as response: result = json.loads(response.read().decode()) # Parse LLM response content = result.get('output', {}).get('choices', [{}])[0].get('message', {}).get('content', '{}') return json.loads(content) except: return simple_sentiment_analysis(text)python sentiments = [] for i, tweet in enumerate(tweets[:10], 1): text = tweet.get('text', '') analysis = analyze_sentiment_llm(text) sentiments.append(analysis.get('score', 0.5)) emoji = "🚀" if analysis.get('sentiment') == 'bullish' else "📉" if analysis.get('sentiment') == 'bearish' else "➡️" print(f"{i}. {emoji} Score: {analysis.get('score', 0.5):.2f}") print(f" {text[:80]}...") print() # Calculate average avg_score = sum(sentiments) / len(sentiments) if sentiments else 0.5 print("=" * 60) print(f"📊 {coin_symbol} 情绪分析结果:") print(f" 平均分数:{avg_score:.2f}/1.00") if avg_score > 0.7: print(f" 情绪:🚀 非常看涨 (Very Bullish)") print(f" 信号:💰 考虑买入") elif avg_score > 0.5: print(f" 情绪:📈 ...[truncated 3208 chars]- Remediation
View remediation
Remediation Suggestions
- Establish an explicit trust boundary for source content. Place the sentiment-analysis policy in a system message and pass tweet content in a separately delimited data field. Explicitly state that instructions, JSON examples, and requests inside source content must be treated only as quoted material.
- Use structured output controls. If supported by the model API, require a JSON schema or tool/function response rather than accepting unrestricted text.
- Validate every model response before use. Require an object with:
sentimentrestricted tobullish,bearish, orneutral;scoreandconfidencerestricted to finite numeric values from0.0through1.0;keywordsrestricted to a bounded list of strings.
- Reject invalid results safely. Do not silently accept out-of-range or incorrectly typed fields. Discard invalid analyses or replace them with a clearly identified local fallback result.
- Reduce the influence of individual posts. Apply duplicate detection, source-quality controls, robust aggregation, and per-source weighting so one or a few attacker-controlled posts cannot dominate the result.
- Treat output as untrusted even when JSON parsing succeeds. JSON syntax validation alone does not provide semantic validation or protection against indirect prompt injection.
- Add adversarial tests. Test posts containing instruction overrides, forged JSON, extreme and non-finite values, strings in numeric fields, nested objects, and contradictory sentiment/score combinations.
- Avoid presenting model output as actionable financial guidance without safeguards. Clearly label confidence and provenance, surface invalid or insufficient data, and require corroboration before generating buy- or sell-oriented messages.
