Man in the middle using Playwright
Tags: javascript, playwright, mitm, devtools
Published: 2020-11-09 14:28:23

## Prologue
As a Front End developer, **I was wondering:** _if  there is a MITM tool targeted to WEB Developer for easily intercept request and manipulate (mock, cache, logs, modify by content-type) the request / response,  having capability of HOT RELOADING rule(s) with additional functionality live in Devtools to edit/enhance/toggle the rule(s)_.

### These have been my Front End Developer needs:
#### It's a rule based routing and scripted with JavaScript Object Literal.
#### Intercept Live JS / CSS and substitute with local development code contains an inline-source-map
#### Manipulate headers either request or response, ie: changing Content Security Policy (CSP) rule
#### Helper to add Javascript code into the HTML response easily ie: add to the header or at the end of body
#### Define a tag to some rules and during runtime it can be toggle to enable/disable rule
#### A flexible rule should start with simple then extend as needed: 
Start with simple URL matching and response with an empty string:
```js
response: {
  { 'GET:doubleclick.net': '' } // GET url contains 'doubleclick.net'
  { 'doubleclick.net': '' } // match url contains 'doubleclick.net' 
}
```
Or morph to function based:
```js
response: {
  'doubleclick.net': {
    response(resp) {
      const body = '';
      return { body };
    }
  }
} 
```
Or specific to `js`
```js
js: {
  'doubleclick.net': {
    response(resp) {
      const body = '';
      return { body };
    }
  }
} 
```
Not replacing, just need to `inject at the end of response payload` with special syntax `=>`
```js
const jscode = 'alert(0)';
...
js: {
  'doubleclick.net': `=>${jscode}`
} 
```

## Introducing Mitm-Play
TLDR; the term "Man in the Middle" can be check to `MITM related articles` published by: [cyris](https://dev.to/sudo_overflow/reverse-engineering-a-private-api-with-mitm-proxy-20ia), [Kyle Parisi](https://dev.to/kyleparisi/charles-proxy-1pnb), [Kevin Cui](https://dev.to/kevcui/3-mitmproxy-tips-you-might-not-know-about-5dbg).

[Mitm-Play](https://www.npmjs.com/package/mitm-play) is a MITM leaning toward my need as FE Developer during Development or debugging PROD, detail documentation can be found on [github](https://github.com/mitm-proxy/mitm-play), utilize Playwright `route('**', EventHandler) + Chrome Plugins`   

### Installation
Mitm-Play is a CLI App, the installation should be on global scope 
```js
npm i -g mitm-play
```

### First run
It will prompt you to create demo routes 
```bash
>>> mitm-play -s

Create ~/user-route (Y/n)? y [Enter]
```
Next, chromium will be launch and auto navigate to https://keybr.com. Open Chrome Devtools to access Mitm-Play plugin.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xowul0g9mp5lc9hkjxu1.png)

At first launch **no rules getting applied**, as we can see on the image above in `Devtool` section: `mitm-play/Tags`, there are **no tags getting checked**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pdzgzzobm0ru9xmy385d.png)

Some `keys` having `:no-ads` and it is a `tags` attached to **mock** & **css** rules, and the `tags` will be available as a `checkbox option` to enable/disable rule(s). The **state** is determined by **tags** `key` in which having an `empty array`, so `no rule getting applied`.
```js
route = { tags: [], 'mock:no-ads', 'css:no-ads' }
```
To enable at first, either delete the `tags` key, or add corresponding tags: [`'no-ads'`]
```js
route = { tags: ['no-ads'],...
```

## Epilogue
This introduction may be too `simple interception use case`, but I think it serve at least minimum demo that can be showcase immediately after installation, later time can be expand to different scenario with different rules.

To get the idea, I end this post with `the skeleton of route` :
```js
route = {
  url:     '',
  urls:    {},
  title:   '',
  jsLib:   [],
  workspace: '',
  screenshot: {}, //user interaction rules & observe DOM-Element
  skip:    [], //start routing rules
  proxy:   [], //request with proxy
  noproxy: [], 
  nosocket:[],
  request: {},
  mock:    {}, 
  cache:   {},
  log:     {},
  html:    {},
  json:    {},
  css:     {},
  js:      {},
  response:{}, //end routing rules
}
```