Test Circumvention of Work Flows
Scanned 9/3/2026
Install to Claude Code
npx -y skills add CyberStrikeus/CyberStrike --skill wstg-busl-06 --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Wstg Busl 06?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/cyberstrikeus-wstg-busl-06)More formats (shields.io, HTML) on the badges page.
---
name: wstg-busl-06
description: "Test Circumvention of Work Flows"
category: business-logic
owasp_id: WSTG-BUSL-06
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-06
## Test ID
WSTG-BUSL-06
## Test Name
Testing for the Circumvention of Work Flows
## High-Level Description
Workflow circumvention testing examines whether an application properly enforces the intended sequence of steps in multi-step processes. Many business processes require specific steps to be completed in order (e.g., shopping cart → checkout → payment → confirmation). Attackers may attempt to skip steps, revisit completed steps, or access endpoints out of sequence to bypass security controls, avoid payments, or gain unauthorized access.
---
## What to Check
### Workflow Elements
- [ ] Step sequence enforcement
- [ ] State validation between steps
- [ ] Direct URL/endpoint access
- [ ] Back button/history manipulation
- [ ] Bookmark/link sharing vulnerabilities
- [ ] Parameter manipulation for step skipping
### Common Workflow Vulnerabilities
| Vulnerability | Example |
| ------------------ | ------------------------------------------------ |
| Step skipping | Skip payment, go directly to order confirmation |
| Step repetition | Repeat discount application |
| State manipulation | Change order after payment |
| Direct access | Access confirmation page without completing flow |
| Parallel execution | Start multiple flows, complete one |
---
## How to Test
### Step 1: Map the Workflow
```bash
# Document all steps in the workflow
# Example: E-commerce checkout
# 1. Add to cart: POST /api/cart/add
# 2. View cart: GET /api/cart
# 3. Apply coupon: POST /api/cart/coupon
# 4. Checkout: POST /api/checkout/start
# 5. Enter shipping: POST /api/checkout/shipping
# 6. Enter payment: POST /api/checkout/payment
# 7. Confirm order: POST /api/checkout/confirm
# 8. Order complete: GET /api/orders/{id}
# Capture all requests through each step
# Note: URLs, parameters, tokens, session changes
```
### Step 2: Test Direct Step Access
```bash
# Try to access later steps directly without completing earlier ones
# Start fresh session
# Skip to checkout confirmation
curl -s -X POST "https://target.com/api/checkout/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"order_id": "12345"}'
# Skip to order complete
curl -s "https://target.com/api/orders/12345" \
-H "Authorization: Bearer $TOKEN"
# Skip payment step
curl -s -X POST "https://target.com/api/checkout/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cart_id": "abc123",
"shipping_id": "ship123"
}'
# Note: No payment token
```
### Step 3: Test Step Skipping
```bash
#!/bin/bash
# Test if steps can be skipped
TOKEN="your_auth_token"
BASE="https://target.com"
# Normal flow: 1 -> 2 -> 3 -> 4 -> 5
# Test: 1 -> 3 (skip step 2)
echo "Step 1: Start checkout"
checkout=$(curl -s -X POST "$BASE/api/checkout/start" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"cart_id": "cart123"}')
checkout_id=$(echo $checkout | jq -r '.checkout_id')
echo "Skip step 2, go to step 3..."
# Skip shipping, go directly to payment
result=$(curl -s -X POST "$BASE/api/checkout/payment" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"checkout_id\": \"$checkout_id\",
\"payment_method\": \"card\",
\"card_token\": \"tok_test\"
}")
echo "Result: $result"
# If accepted, workflow can be circumvented
```
### Step 4: Test State Manipulation After Completion
```bash
# Test if completed steps can be modified
# Complete checkout normally
# Then try to modify earlier steps
# Try changing shipping after payment
curl -s -X PUT "https://target.com/api/checkout/abc123/shipping" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"address": "New Address",
"city": "Attacker City"
}'
# Try re-applying coupon after order is placed
curl -s -X POST "https://target.com/api/orders/order123/apply-coupon" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"code": "DISCOUNT50"}'
```
### Step 5: Test Workflow Token/State Bypass
```bash
# Analyze workflow state tokens
# Look for predictable patterns
# Example: If checkout uses sequential IDs
# Current: checkout_100
# Try: checkout_99, checkout_101
for id in 95 96 97 98 99 100 101 102; do
response=$(curl -s "https://target.com/api/checkout/checkout_$id/confirm" \
-H "Authorization: Bearer $TOKEN")
echo "checkout_$id: $response"
done
# Try with modified state tokens
curl -s -X POST "https://target.com/api/checkout/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"checkout_id": "checkout_99",
"state_token": "modified_token",
"step": "complete"
}'
```
### Step 6: Test Parallel Workflow Execution
```bash
#!/bin/bash
# Test parallel workflow abuse
# Start multiple checkouts
for i in {1..5}; do
curl -s -X POST "https://target.com/api/checkout/start" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"cart_id": "cart123"}' &
done
wait
# Try to complete them all with single payment
# Or complete one and cancel others after benefits applied
```
### Step 7: Test Registration/Onboarding Bypass
```bash
# Test if onboarding steps can be bypassed
# Try accessing main app without completing onboarding
curl -s "https://target.com/api/dashboard" \
-H "Authorization: Bearer $NEW_USER_TOKEN"
# Try skipping email verification
curl -s -X POST "https://target.com/api/users/complete-profile" \
-H "Authorization: Bearer $UNVERIFIED_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Test User"}'
# Try skipping 2FA setup if required
curl -s "https://target.com/api/sensitive-data" \
-H "Authorization: Bearer $NO_2FA_TOKEN"
```
---
## Tools
### Manual Testing
| Tool | Description | Usage |
| -------------------- | --------------------- | ---------------------- |
| **Burp Suite** | Intercept workflow | Modify/replay requests |
| **Postman** | API workflow testing | Collection runners |
| **Browser DevTools** | Monitor state changes | Track tokens/cookies |
### Automated
| Tool | Description |
| ------------------ | ------------------------- |
| **Burp Macros** | Automate multi-step flows |
| **Custom scripts** | Workflow fuzzing |
---
## Example Commands/Payloads
### Workflow State Manipulation
```json
// Step indicator manipulation
{"current_step": 5}
{"step": "complete"}
{"workflow_state": "finished"}
// Status manipulation
{"payment_status": "completed"}
{"verified": true}
{"approved": true}
// Skip flags
{"skip_verification": true}
{"express_checkout": true}
{"bypass_review": true}
```
### Workflow Circumvention Tester
```python
#!/usr/bin/env python3
import requests
class WorkflowTester:
def __init__(self, base_url, token):
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
self.findings = []
def test_direct_step_access(self, steps):
"""Test if later steps can be accessed directly"""
for i, step in enumerate(steps):
if i == 0:
continue # Skip first step
# Try accessing without completing previous steps
response = requests.request(
step["method"],
f"{self.base_url}{step['endpoint']}",
headers=self.headers,
json=step.get("payload", {})
)
if response.status_code == 200:
self.findings.append({
"type": "direct_access",
"step": i + 1,
"endpoint": step["endpoint"],
"result": "VULNERABLE - Step accessible without prior steps"
})
else:
self.findings.append({
"type": "direct_access",
"step": i + 1,
"endpoint": step["endpoint"],
"result": f"Protected - Status {response.status_code}"
})
def test_step_skipping(self, steps):
"""Test skipping intermediate steps"""
# Complete first step
first = steps[0]
r1 = requests.request(
first["method"],
f"{self.base_url}{first['endpoint']}",
headers=self.headers,
json=first.get("payload", {})
)
if r1.status_code != 200:
return
# Try to skip to later steps
for i in range(2, len(steps)):
step = steps[i]
response = requests.request(
step["method"],
f"{self.base_url}{step['endpoint']}",
headers=self.headers,
json=step.get("payload", {})
)
if response.status_code == 200:
self.findings.append({
"type": "step_skipping",
"skipped_to": i + 1,
"endpoint": step["endpoint"],
"result": f"VULNERABLE - Skipped steps 2-{i}"
})
def test_backward_navigation(self, steps, completed_step):
"""Test if earlier steps can be modified after completion"""
# Assume workflow completed to completed_step
for i in range(completed_step):
step = steps[i]
# Try to modify earlier step
if step["method"] in ["POST", "PUT"]:
response = requests.request(
step["method"],
f"{self.base_url}{step['endpoint']}",
headers=self.headers,
json=step.get("payload", {})
)
if response.status_code == 200:
self.findings.append({
"type": "backward_modification",
"step": i + 1,
"endpoint": step["endpoint"],
"result": "VULNERABLE - Earlier step modifiable"
})
def generate_report(self):
"""Generate test report"""
print("\n=== WORKFLOW CIRCUMVENTION REPORT ===\n")
vulnerabilities = [f for f in self.findings if "VULNERABLE" in f["result"]]
print(f"Total tests: {len(self.findings)}")
print(f"Vulnerabilities: {len(vulnerabilities)}")
if vulnerabilities:
print("\n--- VULNERABILITIES ---")
for v in vulnerabilities:
print(f" [{v['type']}] {v['endpoint']}: {v['result']}")
return self.findings
# Usage
tester = WorkflowTester("https://target.com", "auth_token")
checkout_steps = [
{"method": "POST", "endpoint": "/api/checkout/start", "payload": {"cart_id": "cart123"}},
{"method": "POST", "endpoint": "/api/checkout/shipping", "payload": {"address_id": "addr1"}},
{"method": "POST", "endpoint": "/api/checkout/payment", "payload": {"payment_token": "tok1"}},
{"method": "POST", "endpoint": "/api/checkout/confirm", "payload": {}},
]
tester.test_direct_step_access(checkout_steps)
tester.test_step_skipping(checkout_steps)
tester.generate_report()
```
---
## Remediation Guide
### 1. Implement Workflow State Machine
```python
from enum import Enum
from datetime import datetime
class CheckoutState(Enum):
INITIATED = "initiated"
CART_REVIEWED = "cart_reviewed"
SHIPPING_ADDED = "shipping_added"
PAYMENT_ADDED = "payment_added"
CONFIRMED = "confirmed"
COMPLETED = "completed"
class CheckoutStateMachine:
VALID_TRANSITIONS = {
CheckoutState.INITIATED: [CheckoutState.CART_REVIEWED],
CheckoutState.CART_REVIEWED: [CheckoutState.SHIPPING_ADDED],
CheckoutState.SHIPPING_ADDED: [CheckoutState.PAYMENT_ADDED],
CheckoutState.PAYMENT_ADDED: [CheckoutState.CONFIRMED],
CheckoutState.CONFIRMED: [CheckoutState.COMPLETED],
CheckoutState.COMPLETED: []
}
def can_transition(self, current, target):
"""Check if transition is valid"""
allowed = self.VALID_TRANSITIONS.get(current, [])
return target in allowed
def transition(self, checkout, target_state):
"""Perform state transition with validation"""
if not self.can_transition(checkout.state, target_state):
raise WorkflowViolationError(
f"Cannot transition from {checkout.state} to {target_state}"
)
checkout.state = target_state
checkout.state_history.append({
"from": checkout.state,
"to": target_state,
"timestamp": datetime.utcnow()
})
return checkout
# Usage in endpoint
@app.route('/api/checkout/payment', methods=['POST'])
def add_payment():
checkout = get_checkout(request.json['checkout_id'])
# Validate state before processing
if checkout.state != CheckoutState.SHIPPING_ADDED:
return jsonify({
"error": "Invalid workflow state",
"expected": "shipping_added",
"current": checkout.state.value
}), 400
# Process payment
process_payment(checkout, request.json)
# Transition state
state_machine.transition(checkout, CheckoutState.PAYMENT_ADDED)
return jsonify(checkout.to_dict())
```
### 2. Cryptographic State Tokens
```python
import jwt
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
def generate_workflow_token(checkout_id, current_step, user_id):
"""Generate signed token for workflow state"""
payload = {
"checkout_id": checkout_id,
"step": current_step,
"user_id": user_id,
"completed_at": datetime.utcnow().isoformat(),
"exp": datetime.utcnow() + timedelta(hours=1)
}
return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
def validate_workflow_token(token, expected_step, checkout_id, user_id):
"""Validate workflow token"""
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
# Verify all components
if payload["checkout_id"] != checkout_id:
return False, "Invalid checkout"
if payload["user_id"] != user_id:
return False, "Invalid user"
if payload["step"] != expected_step - 1:
return False, f"Invalid step sequence"
return True, None
except jwt.ExpiredSignatureError:
return False, "Token expired"
except jwt.InvalidTokenError:
return False, "Invalid token"
@app.route('/api/checkout/payment', methods=['POST'])
def add_payment():
# Require token from previous step
prev_token = request.headers.get('X-Workflow-Token')
if not prev_token:
return jsonify({"error": "Workflow token required"}), 400
valid, error = validate_workflow_token(
prev_token,
expected_step=3, # Current step number
checkout_id=request.json['checkout_id'],
user_id=current_user.id
)
if not valid:
return jsonify({"error": error}), 400
# Process and generate new token for next step
process_payment(request.json)
new_token = generate_workflow_token(
request.json['checkout_id'],
current_step=3,
user_id=current_user.id
)
return jsonify({
"status": "success",
"workflow_token": new_token
})
```
### 3. Server-Side Step Tracking
```python
class WorkflowTracker:
def __init__(self, redis_client):
self.redis = redis_client
def record_step_completion(self, workflow_id, user_id, step):
"""Record completed step"""
key = f"workflow:{workflow_id}:{user_id}"
self.redis.sadd(key, step)
self.redis.expire(key, 3600) # 1 hour expiry
def verify_prerequisites(self, workflow_id, user_id, target_step, required_steps):
"""Verify all required steps are completed"""
key = f"workflow:{workflow_id}:{user_id}"
completed = self.redis.smembers(key)
missing = set(required_steps) - completed
if missing:
return False, list(missing)
return True, None
def lock_completed_steps(self, workflow_id, user_id, step):
"""Lock step to prevent modification"""
key = f"workflow_lock:{workflow_id}:{user_id}"
self.redis.sadd(key, step)
def is_step_locked(self, workflow_id, user_id, step):
"""Check if step is locked"""
key = f"workflow_lock:{workflow_id}:{user_id}"
return self.redis.sismember(key, step)
```
---
## Risk Assessment
### CVSS Score
| Finding | CVSS | Severity |
| ---------------------------------- | ---- | -------- |
| Payment step bypass | 9.8 | Critical |
| Verification step bypass | 8.8 | High |
| Discount application after payment | 7.5 | High |
| Onboarding bypass | 6.5 | Medium |
| Step modification after completion | 6.5 | Medium |
---
## CWE Categories
| CWE ID | Title | Description |
| ----------- | -------------------------------------------- | ----------------------- |
| **CWE-841** | Improper Enforcement of Behavioral Workflow | Workflow bypass |
| **CWE-306** | Missing Authentication for Critical Function | Step skipping |
| **CWE-840** | Business Logic Errors | Logic flaw exploitation |
---
## References
- [OWASP WSTG - Test Circumvention of Work Flows](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/10-Business_Logic_Testing/06-Test_Circumvention_of_Work_Flows)
- [OWASP Business Logic Security](https://owasp.org/www-community/vulnerabilities/Business_logic_vulnerability)
- [State Machine Security Patterns](https://cheatsheetseries.owasp.org/cheatsheets/Transaction_Authorization_Cheat_Sheet.html)
---
## Checklist
```
[ ] Workflow steps mapped and documented
[ ] Direct step access tested
[ ] Step skipping tested
[ ] State manipulation tested
[ ] Backward navigation tested
[ ] Parallel workflow tested
[ ] Token/state prediction tested
[ ] Registration/onboarding bypass tested
[ ] Payment bypass tested
[ ] State machine enforcement verified
[ ] Findings documented
[ ] Remediation recommendations provided
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!