Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython

pymiproxy is unavailable in PyPM, because there aren't any builds for it in the package repositories. Click the linked icons to find out why.

 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
1.0 Failed View build log
Windows (64-bit)
1.0 Failed View build log
Mac OS X (10.5+)
1.0 Failed View build log
Linux (32-bit)
1.0 Failed View build log
Linux (64-bit)
1.0 Failed View build log
 
Links
Author
License
GPL
Dependencies
Depended by
Lastest release
version 1.0 on May 11th, 2013

#pymiproxy - Python Micro Interceptor Proxy

A small and sweet man-in-the-middle proxy capable of doing HTTP and HTTP over SSL.

##Introduction

pymiproxy is a small, lightweight, man-in-the-middle proxy capable of performing HTTP and HTTPS (or SSL) inspection. The proxy provides a built-in certificate authority that is capable of generating certificates for SSL-based destinations. Pymiproxy is also extensible and provides two methods for extending the proxy: method overloading, and a pluggable interface. It is ideal for situations where you're in dire need of a cool proxy to tamper with out- and/or in-bound HTTP data.

##Installation Requirements

The following modules are required:

  • pyOpenSSL

##Installation

Just run the following command at the command prompt:

`bash $ sudo python setup.py install `

##Usage

The module offers a few examples in the code. In brief, pymiproxy can be run right-away by issuing the following command at the the command-prompt:

`bash $ python -m miproxy.proxy `

This will invoke pymiproxy with the `DebugInterceptor` plugin which simply outputs the first 100 bytes of each request and response. The proxy runs on port 8080 and listens on all addresses. Go ahead and give it a try.

##Extending or Implementing pymiproxy

There are two ways of extending the proxy:

  • Develop and register an Interceptor plugin; or
  • Overload the `mitm_request`, and `mitm_response` methods in the `ProxyHandler` class.

The decision on which method you choose to use is entirely dependant on whether or not you wish to push the data being intercepted through a set of interceptors or not.

###Interceptor Plugins

There are currently two types of interceptor plugins:

  • `RequestInterceptorPlugins`: executed prior to sending the request to the remote server; and
  • `ResponseInterceptorPlugins`: executed prior to sending the response back to the client.

The following flow is taken by pymiproxy in this mode:

  1. Client request received
  2. Client request parsed
  3. Client request processed/transformed by Request Interceptor plugins
  4. Updated request sent to remote server
  5. Response received by remote server
  6. Response processed/transformed by Response Interceptor plugins
  7. Updated response sent to client

You can register as many plugins as you wish. However, keep in mind that plugins are executed in the order that they are registered in. Take care in how you register your plugins if the result of one plugin is dependent on the result of another.

The following is a simple code example of how to run the proxy with plugins:

```python from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy

System Message: WARNING/2 (<string>, line 77); backlink

Inline literal start-string without end-string.

System Message: WARNING/2 (<string>, line 77); backlink

Inline interpreted text or phrase reference start-string without end-string.

class DebugInterceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):

def do_request(self, data):
print '>> %s' % repr(data[:100]) return data
def do_response(self, data):
print '<< %s' % repr(data[:100]) return data
if __name__ == '__main__':

proxy = None if not argv[1:]:

System Message: ERROR/3 (<string>, line 94)

Unexpected indentation.
proxy = AsyncMitmProxy()

System Message: WARNING/2 (<string>, line 95)

Block quote ends without a blank line; unexpected unindent.
else:
proxy = AsyncMitmProxy(ca_file=argv[1])

System Message: WARNING/2 (<string>, line 97)

Definition list ends without a blank line; unexpected unindent.

proxy.register_interceptor(DebugInterceptor) try:

System Message: ERROR/3 (<string>, line 99)

Unexpected indentation.
proxy.serve_forever()

System Message: WARNING/2 (<string>, line 100)

Block quote ends without a blank line; unexpected unindent.
except KeyboardInterrupt:
proxy.server_close()

System Message: WARNING/2 (<string>, line 102)

Definition list ends without a blank line; unexpected unindent.

```

System Message: WARNING/2 (<string>, line 102); backlink

Inline literal start-string without end-string.

System Message: WARNING/2 (<string>, line 102); backlink

Inline interpreted text or phrase reference start-string without end-string.

###Method Overloading

The alternate approach to extending the proxy functionality is to subclass the ProxyHandler class and overload the `mitm_request` and `mitm_response` methods. The following is a quick example:

```python from miproxy.proxy import AsyncMitmProxy

System Message: WARNING/2 (<string>, line 109); backlink

Inline literal start-string without end-string.

System Message: WARNING/2 (<string>, line 109); backlink

Inline interpreted text or phrase reference start-string without end-string.

class MitmProxyHandler(ProxyHandler):

def mitm_request(self, data):
print '>> %s' % repr(data[:100]) return data
def mitm_response(self, data):
print '<< %s' % repr(data[:100]) return data
if __name__ == '__main__':

proxy = None if not argv[1:]:

System Message: ERROR/3 (<string>, line 126)

Unexpected indentation.
proxy = AsyncMitmProxy(RequestHandlerClass=MitmProxyHandler)

System Message: WARNING/2 (<string>, line 127)

Block quote ends without a blank line; unexpected unindent.
else:
proxy = AsyncMitmProxy(RequestHandlerClass=MitmProxyHandler, ca_file=argv[1])
try:
proxy.serve_forever()
except KeyboardInterrupt:
proxy.server_close()

System Message: WARNING/2 (<string>, line 133)

Definition list ends without a blank line; unexpected unindent.

```

System Message: WARNING/2 (<string>, line 133); backlink

Inline literal start-string without end-string.

System Message: WARNING/2 (<string>, line 133); backlink

Inline interpreted text or phrase reference start-string without end-string.

Note: In both cases, the methods that process the data need to return the data back to the proxy handler. Otherwise, you'll get an exception.

##Kudos

Thanks to the great documentation at python.org, GnuCitizen's PDP for the ideas, the pyOpenSSL group for making a great OpenSSL API.

Subscribe to package updates

Last updated May 11th, 2013

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.