- Location
- bounty_hunter.py:268
- Finding
- Untrusted Bounty Content Is Embedded Directly in an AI Instruction Prompt<![CDATA[
## Vulnerability Details
**File Location**: `bounty_hunter.py:268-313`
**Vulnerability Type**: Indirect prompt injection and unsafe rendering of model output
**Risk Level**: Medium
### Vulnerable Code
```python
# Build compact bounty summaries for the prompt
summaries = []
for i, b in enumerate(bounties):
summaries.append({
"idx": i,
"title": b.get("title", ""),
"price": b.get("price", 0),
"hours": b.get("estimatedHours", 0),
"category": b.get("category", ""),
"skills": b.get("skillsNeeded", []),
"remote": b.get("location", {}).get("isRemoteAllowed", False),
"spots": b.get("spotsAvailable", 1),
"desc": (b.get("description", "") or "")[:300],
})
prompt = (
"You are a bounty evaluator for a freelance platform. Score each bounty 0-100 "
"based on: pay rate, feasibility, location requirements (I'm in northern Ohio, USA) skill match (python, web dev, "
"AI, automation, marketing, writing, research, vibe coach, photographer, telegram, psychologist, life coach, mcp, design), remote availability, and description quality.\n\n"
"IMPORTANT: These should be REAL JOB POSTINGS where someone pays for work to be done. "
"Score < 10 for 'for hire' self-promotions (people advertising their own skills/services, "
"résumés, 'hire me' posts). Only score high for actual tasks/gigs with clear deliverables.\n\n"
"Flag scams (crypto deposits, upfront payments, suspicious links) with score < 20.\n\n"
f"Bounties:\n{json.dumps(summaries)}\n\n"
"Respond with ONLY a JSON array, no markdown, no explanation:\n"
'[{"idx": 0, "score": 90, "reason": "Good pay, skill match"}, ...]'
)
try:
r = requests.post(
"https://api.x.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {XAI_API_KEY}", "Content-Type": "application/json"},
json={
"model": "grok-4-1-fast-reasoning",
"messages": [{"role": "user", "content":
...[truncated 3642 chars]
- Remediation
- <![CDATA[
## Remediation Suggestions
1. Treat every bounty field as untrusted data and clearly delimit it from system instructions.
2. Use separate system and user messages, with the system message explicitly prohibiting obedience to instructions found in bounty content.
3. Prefer schema-constrained or structured model output when supported by the API.
4. Validate that the response is an array of objects with unique, in-range integer indices.
5. Require scores to be finite numeric values between 0 and 100.
6. Limit reasons to a conservative character count and reject unexpected control characters or markup.
7. Escape Telegram Markdown metacharacters in titles, names, reasons, and all other untrusted fields.
8. Reapply deterministic scam and self-promotion checks after AI scoring so model output cannot bypass local controls.
9. Detect suspicious instruction-like phrases in bounty content and either exclude those records from AI scoring or flag them for manual review.
10. Preserve a non-AI heuristic score and display discrepancies between deterministic and model-generated rankings.
]]>