Skip to content
Bugwise
Menu
Mobile Testing

Proxy Tools: Charles and Proxyman

See every request your app sends, change server responses on the fly, and simulate errors and slow networks. A practical introduction to Charles and Proxyman for mobile testers.

30 min intermediate Mobile

A banking app shows the wrong balance for some users. The developers say “the app just displays what the server sends”. The backend team says “the server sends the right number”. Who’s right?

A tester with a proxy tool settles it in two minutes: she opens the request, looks at the response, and sees the server sends "balance": 1250.5 while the app shows $125.05. It’s an app bug, and she has the evidence. No guessing, no meetings.

That’s the superpower of a proxy toolProxy toolA program that sits between the app and the server so you can watch and change network traffic.Open in glossary →: it lets you see and change the conversation between the app and its server.

What a proxy does

Normally the app on your phone talks straight to the server. With a proxy, you tell the phone to send its traffic through a program on your computer first. The proxy sits in the middle: it records every request and response, and can pause, edit, slow down or replace them.

Phone

Wi-Fi proxy points to your computer

Proxy on your computer

Charles, Proxyman, Fiddler, mitmproxy

RecordInspectBreakpointMap LocalThrottleRepeat

Server

api.shop.example

For HTTPS traffic, the phone must trust the proxy’s root certificate. The proxy decrypts the traffic, shows it to you, and encrypts it again before passing it on.

This is a man-in-the-middle setup, the same thing an attacker would try to do, except you do it on purpose, on your own test device, with your team’s permission. For HTTPSHTTPSThe secure version of HTTP; traffic between the browser or app and the server is encrypted.Open in glossary → traffic, the phone must trust the proxy’s own certificateSSL certificateThe certificate that lets a browser or app verify a server's identity and encrypt traffic (HTTPS).Open in glossary →, otherwise the encryption prevents the proxy from reading anything.

Why testers use proxies

What you can doWhy it’s usefulExample
See requests and responsesFind out whether a bug is in the app or the serverThe server sends the right price, the app shows the wrong one
Verify analytics eventsCheck events fire once, at the right moment, with the right datapurchase event sent twice, or with the wrong currency
Check what data is sentSpot privacy and security problemsPassword in the URL, full card number in a response, tokens over plain HTTP
Simulate errorsTest how the app handles a 500, 401 or 404 you can’t trigger otherwiseThe app shows a blank screen on a server error
BreakpointsPause a request or response and edit it before it continuesChange a price to 0.01, a name to 300 characters, or a status to 500
Map Local / Map RemoteAnswer with a local file, or send the request to another serverReturn an empty list; point the app at the staging server
ThrottleSlow down all traffic from the phoneCheck loading states on 3G (see Network Conditions)
Repeat requestsSend the same request again, many timesDoes sending “place order” twice create two orders?

Try it: the proxy playground

Play with a proxy before setting up a real one. This grocery app is well built: it handles errors, empty lists and slow responses correctly. Use the tools and watch how it reacts.

🧪 Proxy playground

The grocery app on the phone talks to its server through the proxy. Try this: turn on Breakpoint, tap refresh in the app, change a price or the status code, then press Execute. Then try Map Local and Throttle.

Proxy · recording on 192.168.1.20:8888
MethodHost / pathStatusTime
  • Use the app on the phone to see its traffic here.

Select a request to see its details.

9:41

FreshCart

Setting up a real proxy

The steps are similar for every tool. Here’s the big picture, then the details for Charles and Proxyman.

  1. Install the proxy on your computer and start it. Note its IP address and port (Charles uses 8888 by default, Proxyman 9090).
  2. Put the phone and computer on the same Wi-Fi network. Office “guest” networks often block devices from seeing each other; use a network that allows it.
  3. Set the phone’s Wi-Fi proxy to Manual, with the computer’s IP and the proxy port. Open any page and accept the “allow this device?” prompt on the computer.
  4. Install and trust the proxy’s root certificate on the phone, so HTTPS traffic can be decrypted.
  5. Enable SSL proxying for the hosts you want to inspect (for example api.shop.example).
  6. Use the app and watch the traffic. When you’re done, remove the proxy setting from the phone.

Charles and Proxyman specifics

Charles Proxy runs on macOS, Windows and Linux (paid, with a free trial).

  • See your IP and port: Help → Local IP Address and Proxy → Proxy Settings (default port 8888).
  • Certificate instructions for phones: Help → SSL Proxying → Install Charles Root Certificate on a Mobile Device or Remote Browser. With the phone’s proxy set, open chls.pro/ssl in the phone’s browser to download it.
  • Decrypt HTTPS: Proxy → SSL Proxying Settings… → add the host (and port 443), or right-click a host → Enable SSL Proxying.
  • Tools: Breakpoints (right-click a request), Tools → Map Local / Map Remote / Rewrite, Proxy → Throttle Settings, and Repeat / Repeat Advanced on any request.

Proxyman is a native macOS app (with Windows and Linux versions, and a free tier).

  • See your IP and port in the app’s status bar or Certificate → Install Certificate on iOS → Physical Devices…, which shows step-by-step instructions (default port 9090).
  • With the phone’s proxy set, open proxy.man/ssl in the phone’s browser to download the certificate. There are similar guides under Certificate for Android devices, the iOS Simulator and the Android emulator.
  • Decrypt HTTPS: right-click a domain → Enable SSL Proxying (Proxyman shows <encrypted> until you do).
  • Tools: Tools → Breakpoint, Map Local, Map Remote, Scripting, Network Conditions (throttling), and Repeat on any request.

Trusting the certificate on the phone

  1. Settings → Wi-Fi → tap the ⓘ next to your network → Configure Proxy → Manual. Enter the computer’s IP and port, and save.
  2. In Safari, open the certificate URL (e.g. chls.pro/ssl or proxy.man/ssl) and allow the profile download.
  3. Settings → General → VPN & Device Management → tap the downloaded profile → Install.
  4. Settings → General → About → Certificate Trust Settings → turn on full trust for the proxy’s root certificate. Skipping this step is the most common reason HTTPS traffic still fails.

The iOS Simulator is easier: Proxyman and Charles can install the certificate into the simulator for you, and the simulator uses the Mac’s proxy settings.

  1. Settings → Network & internet → Internet / Wi-Fi → your network → edit (pencil or gear) → Advanced options → Proxy → Manual. Enter the computer’s IP and port.
  2. Download the certificate from the proxy’s URL in the phone’s browser.
  3. Install it as a CA certificate: usually Settings → Security & privacy → More security settings → Encryption & credentials → Install a certificate → CA certificate (the exact path differs between manufacturers and Android versions).
  4. Important: since Android 7, apps ignore user-installed certificates by default. Ask developers for a debug build whose network security config trusts user certificates, for example:
<!-- res/xml/network_security_config.xml (debug builds only) -->
<network-security-config>
  <debug-overrides>
    <trust-anchors>
      <certificates src="user" />
    </trust-anchors>
  </debug-overrides>
</network-security-config>

In the Android Emulator you can set the proxy in Extended controls → Settings → Proxy.

Other tools

Safety and ethics

What to look for

Data and privacy

Analytics

  • Each event fires exactly once, at the right moment, with the right properties (product ID, price, currency).
  • No events fire before the user gives consent, if the app asks for it.

Error handling

Server-side checks

Common bugs found with a proxy

#BugWhat you seeTypical severity
1Sensitive data in the URL?password=… or ?token=… in the request listHigh
2Over-sharing APIResponse includes full card number, other users’ emails, internal flagsHigh–Critical
3Duplicate analytics eventsSame event appears twice per actionMedium
4Crash on server errorBlank screen or crash after a 500High
5Crash on empty or missing dataApp crashes when a list is empty or a field is nullHigh
6Server trusts the clientEditing price/total in the request changes what is chargedCritical
7Duplicate actions on repeatRepeating “place order” creates a second orderHigh
8Too many requestsThe same data is downloaded 5 times per screenLow–Medium

Find the bug

Time for a real investigation. This grocery app has six bugs that you can only find by looking at (or changing) its traffic. Log in, add items, pay, and use Breakpoint (with Requests and/or Responses), Map Local and the request details. Don’t forget to read the response bodies.

🐞 Bug hunt: Grocery app traffic

This demo has 6 hidden bugs. Explore it like a tester, then check your findings.

Found0/6
9:41

Welcome back

Log in to FreshCart

Email

anna@example.com

Password

••••••••••••

Stuck on a blank screen? Restart the app like a real user would.

Proxy · recording on 192.168.1.20:8888
MethodHost / pathStatusTime
  • Log in on the phone to start capturing traffic.

Select a request to see its details.

  1. 1

    Hint: Log in and read the path of the first request.

  2. 2

    Hint: Tap + once on one product and count the requests to collect.metrics.example.

  3. 3

    Hint: Turn on Breakpoint (Responses), refresh the shop and change the products response to status 500.

  4. 4

    Hint: Turn on Map Local and refresh the shop.

  5. 5

    Hint: Add items, turn on Breakpoint for Requests, tap Pay and edit the total in the order request.

  6. 6

    Hint: Open the GET /v1/me response body.

Example test cases

TC-PRX-001Login does not expose credentials in the URL

Preconditions

  • Proxy recording with SSL proxying enabled for the API host

Steps

  1. Log out
  2. Log in with a test account
  3. Inspect the login request in the proxy

Expected result

Credentials are sent in the body of a POST request over HTTPS. The URL contains no password, email or token.

TC-PRX-002Purchase analytics event fires once with correct data

Preconditions

  • Proxy recording
  • Basket contains 1 item for $12.50

Steps

  1. Complete checkout
  2. Filter the proxy by the analytics host

Expected result

Exactly one "purchase" event is sent after the order succeeds, with value 12.50 and currency USD.

TC-PRX-003Product list handles a 500 error

Preconditions

  • Response breakpoint (or rewrite rule) on GET /v1/products

Steps

  1. Pull to refresh the product list
  2. Change the response status to 500 and execute

Expected result

A friendly error with a "Try again" button is shown. No crash, no blank screen. Try again loads the list once the breakpoint is removed.

TC-PRX-004Product list handles an empty response

Preconditions

  • Map Local rule returns {"products": []} for GET /v1/products

Steps

  1. Open the shop

Expected result

An empty state is shown ("Nothing on the shelves right now"). The app does not crash.

TC-PRX-005Server ignores a manipulated order total

Preconditions

  • Request breakpoint on POST /v1/orders
  • Basket total is $7.99

Steps

  1. Tap Pay
  2. Change "total" to 0.01 in the request body and execute

Expected result

The server rejects the order or charges the correct $7.99 calculated from its own prices.

TC-PRX-006Repeating the place-order request does not create a second order

Preconditions

  • One order just placed while recording

Steps

  1. Select the POST /v1/orders request in the proxy
  2. Use Repeat
  3. Open order history in the app

Expected result

Only one order exists. The repeated request is rejected or returns the original order (idempotency key).

Tip: click a test case to expand it.

Checklist

Proxy testing checklist

0 of 12 checked

Check your understanding

Quick quiz

0/5 answered · 0 correct

  1. 1.You installed the proxy certificate on an iPhone, but HTTPS requests still fail. What did you most likely forget?

  2. 2.An Android app shows no decrypted traffic, although the certificate is installed on the phone. What is a likely reason?

  3. 3.Which proxy feature lets you change a server response before the app receives it?

  4. 4.You change the price in the order request to 0.01 and the server charges 0.01. Whose bug is it, and how severe?

  5. 5.Requests from one app always fail with SSL errors in the proxy, while other apps work. What should you do?

Key takeaways

  • A proxy sits between the app and the server, so you can see and change every request and response.
  • Use it to tell app bugs from server bugs, verify analytics, check what data is sent, simulate errors, throttle and repeat requests.
  • Setup: same network, Wi-Fi proxy on the phone, install and trust the root certificate, enable SSL proxying. Android debug builds must trust user certificates, and pinning needs a QA build.
  • The most valuable proxy findings are security bugs: secrets in URLs, over-sharing APIs and servers that trust client values.
  • Stay safe: test accounts only, don’t share captures with secrets, and remove the proxy and certificate when you’re done.

Finished this page?Nice work, this page is complete!

Mark it as done to track your progress. It's saved in this browser, no account needed.

Its review cards are now in Bites ⚡
Esc

Type to search the whole site.