# mitmproxy: khi tài liệu API nói một đằng, traffic thật nói một nẻo

> Ở site khách, cãi nhau về đặc tả không giải quyết được gì. Đặt một proxy vào giữa và đọc từng byte request, response thường xong chuyện nhanh hơn.

Bản gốc: https://fdetimes.net/vi/cong-cu/mitmproxy-xem-request-that-giua-ung-dung-va-api-khach/

Tài liệu API của khách ghi rằng lỗi xác thực trả về 401. Ứng dụng của bạn thì cứ nhận về một response trông như thành công, rồi vỡ ở bước parse ba tầng phía sau. Cả buổi họp đi vào ngõ cụt: bên khách khẳng định hệ thống chạy đúng như mô tả, bên bạn khẳng định code viết đúng theo tài liệu.

Chỉ một trong hai bên có thể đúng, và bằng chứng nằm ngay trên đường truyền. Thay vì tranh luận về đặc tả, bạn có thể đặt một công cụ vào giữa để mọi người cùng nhìn request và response thật. mitmproxy được làm ra cho đúng việc này.

Nếu bạn làm tích hợp ở site khách, cảnh trên sẽ còn lặp lại nhiều lần. Tài liệu có thể đã cũ so với hệ thống, còn traffic thì luôn phản ánh đúng hệ thống đang chạy.

## mitmproxy thực ra là gì?

Trang chính thức mô tả mitmproxy là HTTPS proxy tương tác, miễn phí và mã nguồn mở, do Aldo Cortesi, Maximilian Hils và Thomas Kriechbaumer làm ra, phát hành theo giấy phép MIT. Chi tiết giấy phép này đáng nhớ, vì nhiều khách hàng có danh sách phần mềm được phép cài trên máy làm việc, và giấy phép là thứ đầu tiên bộ phận IT của họ sẽ hỏi.

Nhóm phát triển gọi nó là "con dao đa năng" cho các việc debug, test, đo mức rò rỉ dữ liệu cá nhân và kiểm thử xâm nhập. Repo trên GitHub ghi rõ đối tượng là cả pentester lẫn software developer.

Bộ công cụ gồm ba chương trình. `mitmproxy` là giao diện dòng lệnh tương tác, `mitmweb` đưa các tính năng chính lên giao diện đồ hoạ chạy trong trình duyệt, còn `mitmdump` dành cho việc viết script và addon.

Ở site khách, `mitmweb` thường hợp cho buổi đầu tiên, vì bạn có thể chia sẻ màn hình và cùng kỹ sư bên khách bấm vào từng request. Khi cần lặp lại một phép kiểm tra hàng trăm lần thì nên chuyển sang `mitmdump`.

## Làm sao nó đọc được HTTPS?

Tài liệu của mitmproxy giải thích ý tưởng cơ bản: với client, nó đóng vai server; với server, nó đóng vai client. Để làm được việc đó với TLS, mitmproxy có sẵn một CA đầy đủ và tạo chứng chỉ giả ngay lúc kết nối. Thiết bị client phải tin CA đó thì kết nối mới thành công.

Chi tiết kỹ thuật này kéo theo một quy tắc nghề nghiệp. Cài một CA lạ lên máy, nhất là máy thuộc hạ tầng của khách, là một thay đổi về bảo mật chứ không còn là mẹo debug. Bạn nên xin phép bằng văn bản, chỉ làm trên môi trường test, và gỡ CA ngay khi xong việc.

Còn một hệ quả nữa: client nào không tin CA của mitmproxy sẽ từ chối kết nối. Nếu ứng dụng báo lỗi chứng chỉ ngay khi bạn bật proxy, hãy kiểm tra bước tin cậy CA trước, đừng vội nghi hệ thống của khách.

## Chọn chế độ nào ở site khách?

Câu hỏi quyết định là bạn có sửa được cấu hình proxy của client hay không. Tài liệu chính thức khuyên dùng explicit proxy, tức là cấu hình client để đi qua mitmproxy, vì đó là cách đơn giản và ổn định nhất. Khi client là code của chính bạn, gần như lúc nào cũng làm được việc này.

| Tình huống ở site khách | Chế độ nên dùng |
|---|---|
| Client là script hoặc service bạn cấu hình được | Explicit proxy (regular mode) |
| Ứng dụng chạy trên cùng máy nhưng không có chỗ đặt proxy | Local capture: bắt traffic trong suốt, không cần cấu hình proxy |
| Không đụng được client, nhưng đặt được một điểm trước service | Reverse proxy: mitmproxy đứng như một server bình thường |

Reverse proxy đặc biệt hữu ích khi hệ thống của khách gọi ngược vào service của bạn, chẳng hạn qua webhook. Bạn đặt mitmproxy trước endpoint của mình và đọc xem bên kia thực sự gửi gì.

## Một ví dụ: bắt quả tang "401" trả về 200

Quay lại tình huống mở bài, coi như một kịch bản giả định. Bạn chạy mitmproxy ở chế độ explicit, cho client của mình đi qua nó, rồi gửi một request với token cố tình sai. Trong `mitmweb`, bạn thấy status 200 và body chứa một trường báo lỗi, không có 401 nào cả.

Mười phút đó thay cho cả buổi họp. Bạn chụp lại cặp request/response, gửi cho kỹ sư bên khách, và cuộc trao đổi chuyển từ "ai sai" sang "xử lý trường hợp này thế nào". Code của bạn cũng nên kiểm tra body lỗi chứ đừng chỉ dựa vào status.

Bước tiếp theo là biến phát hiện đó thành phép kiểm tra tự động. Theo tài liệu, addon là đối tượng Python, mỗi sự kiện như `request` hay `response` ứng với một method. Bản phác thảo dưới đây chỉ in ra những response thành công nhưng body có chữ "error":

```python
class FlagHiddenErrors:
    def response(self, flow):
        body = flow.response.get_text() or ""
        if flow.response.status_code == 200 and "error" in body:
            print("Lỗi ẩn sau 200:", flow.request.pretty_url)

addons = [FlagHiddenErrors()]
```

Chạy bằng `mitmdump -s flag_errors.py`. Script nạp qua `-s` sẽ tự nạp lại khi bạn sửa file, nên bạn chỉnh điều kiện ngay lúc traffic đang chạy mà không phải khởi động lại.

**Điểm mấu chốt:** Tài liệu API có thể đã cũ, còn traffic thật thì không bao giờ cũ.

## Giới hạn cần biết trước

mitmproxy chỉ thấy những gì đi qua nó. Nếu client không được cấu hình đúng, hoặc không tin CA, bạn sẽ gặp một màn hình trống hoặc lỗi TLS và rất dễ kết luận sai. Hãy luôn xác nhận một request đơn giản đã đi qua proxy trước khi đọc request thật.

Nó cũng là công cụ của pentester. Đặt nó vào giữa hệ thống của khách khi chưa được phép có thể thành sự cố bảo mật, dù bạn chỉ định debug. Ngoài ra, traffic bắt được có thể chứa token và dữ liệu thật của khách hàng, nên đừng dán nguyên văn vào ticket hay chat.

## Học gì trước, và kể lại thế nào khi phỏng vấn?

Thứ tự hợp lý là explicit proxy với `mitmweb`, rồi cài và gỡ CA cho sạch sẽ, sau đó một addon nhỏ chạy bằng `mitmdump`. Local capture và reverse proxy để dành cho lúc bạn gặp đúng tình huống cần đến.

Khi được hỏi về một lần tích hợp không chạy như tài liệu, hãy kể theo ba nhịp: triệu chứng, bằng chứng, cách sửa.

Lấy kịch bản ở trên làm khuôn: ứng dụng vỡ ở bước parse; bạn đặt mitmproxy vào giữa và thấy lỗi xác thực trả về 200 kèm body báo lỗi; bạn gửi cặp request/response cho bên khách, sửa code để đọc body lỗi và viết addon bắt mọi trường hợp tương tự.

Câu chuyện đó cho người phỏng vấn thấy bạn làm gì khi hai bên bế tắc, chứ không chỉ cho thấy bạn biết tên một công cụ. Trong CV, hãy rút nó thành một dòng kết quả theo đúng ba nhịp ấy.

Biết tên công cụ chưa đủ để thuyết phục ai. Điều có giá trị là khi hai bên cãi nhau về đặc tả, bạn là người mang được bằng chứng vào phòng họp.

**Thử ngay tuần này:**

- Cài mitmproxy, cho một script gọi API bạn đang dùng đi qua nó ở chế độ explicit proxy, rồi mở mitmweb đọc lại toàn bộ request và response
- Viết một addon có hàm response chỉ in ra các response có status khác 2xx, chạy bằng mitmdump -s, rồi sửa file và xem script tự nạp lại
- Viết một trang ghi chú hai cột 'tài liệu nói / traffic thật cho thấy' cho một tích hợp bạn từng làm, để dùng làm câu chuyện khi đi phỏng vấn

## Nguồn

- [mitmproxy - an interactive HTTPS proxy](https://mitmproxy.org/)

- [GitHub - mitmproxy/mitmproxy](https://github.com/mitmproxy/mitmproxy)

- [How mitmproxy works](https://docs.mitmproxy.org/stable/concepts/how-mitmproxy-works/)

- [Proxy Modes - mitmproxy docs](https://docs.mitmproxy.org/stable/concepts/modes/)

- [Addons overview - mitmproxy docs](https://docs.mitmproxy.org/stable/addons/overview/)
