olmps / web-sniffer

A simple and clean web-traffic proxy sniffer written in typescript
https://olmps.co
MIT License
21 stars 3 forks source link

Change target https port and allow self signed certificates #8

Open DrRek opened 2 years ago

DrRek commented 2 years ago

Hello,

I'm trying to intercept some https traffic and redirect it to another web service. So far I've managed with:

const fs = require('fs')
const Sniffer = require('web-proxy-sniffer')

const proxy = Sniffer.createServer({
  certAuthority: {
    key: fs.readFileSync(`key.pem`),
    cert: fs.readFileSync(`cert.pem`)
  }
})

proxy.intercept({
    // Intercept before the request is sent
    phase: 'request'
  }, (request, response) => {
    // Redirects the request to localhost
    request.headers.host = "localhost"
    console.log(request)

    return request
})

proxy.listen(8083)

But this doesn't work for two reason:

ProxyError: Unknown error at Function.from (/home/luca/projects/stalker_console/socket/backend/node_modules/web-proxy-sniffer/dist/errors/proxy-error.js:38:29) at BridgeServer. (/home/luca/projects/stalker_console/socket/backend/node_modules/web-proxy-sniffer/dist/proxy.js:33:52) at BridgeServer.emit (node:events:394:28) at HttpsServer. (/home/luca/projects/stalker_console/socket/backend/node_modules/web-proxy-sniffer/dist/bridgeServer.js:65:101) at HttpsServer.emit (node:events:394:28) at ClientRequest. (/home/luca/projects/stalker_console/socket/backend/node_modules/web-proxy-sniffer/dist/server.js:69:56) at ClientRequest.emit (node:events:394:28) at TLSSocket.socketErrorListener (node:_http_client:447:9) at TLSSocket.emit (node:events:394:28) at emitErrorNT (node:internal/streams/destroy:157:8) Emitted 'error' event on Proxy instance at: at BridgeServer. (/home/luca/projects/stalker_console/socket/backend/node_modules/web-proxy-sniffer/dist/proxy.js:34:18) at BridgeServer.emit (node:events:394:28) [... lines matching original stack trace ...] at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) { type: 'Unknown Error', original: Error: self signed certificate at TLSSocket.onConnectSecure (node:_tls_wrap:1530:34) at TLSSocket.emit (node:events:394:28) at TLSSocket._finishInit (node:_tls_wrap:944:8) at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:725:12) { code: 'DEPTH_ZERO_SELF_SIGNED_CERT' } }

DrRek commented 2 years ago

I guess one way to solve this might be to

import http from 'http'
import https from 'https'
import ProxyError, { ErrorType } from './errors/proxy-error'
import { IRequest } from './models'

type RouterCallback = (response: http.IncomingMessage) => void

export default class Router {

  static forward(request: IRequest, callback: RouterCallback) {

    const httpRequestOptions: http.RequestOptions = {
      host: request.hostname,
      port: request.port || (request.protocol === 'https:' ? 443 : 80),
      path: request.url,
      method: request.method,
      headers: request.headers
    }

    const httpsRequestOptions: https.RequestOptions = {
      ...httpRequestOptions,
      rejectUnauthorized: false,
      agent: false
    }

    switch (request.protocol) {
      case 'http:': return http.request(httpRequestOptions, (response) => callback(response))
      case 'https:': return https.request(httpsRequestOptions, (response) => callback(response))
      default:  
      throw new ProxyError(
        `Unknown protocol ${request.protocol} received by the Router`,
        ErrorType.inconsistency
      )
    }
  }
}

But I've got no way to test it because I have no idea on how to build ts into node modules