mppx 0.6.8 → 0.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # mppx
2
2
 
3
+ ## 0.6.9
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed Stripe proxy to strip caller-supplied `Stripe-Account` headers before forwarding requests upstream.
8
+
3
9
  ## 0.6.8
4
10
 
5
11
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../../src/proxy/services/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,mBAkB3C;AAED,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,KAAY,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,mDAAmD;QACnD,MAAM,EAAE,MAAM,CAAA;QACd,iEAAiE;QACjE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC5B,MAAM,EACF,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,0BAA0B,GAC1B,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAC3B,mBAAmB,GACnB,sBAAsB,CAAA;KAC3B,CAAC,CAAA;CACH"}
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../../src/proxy/services/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,mBAmB3C;AAED,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,KAAY,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,mDAAmD;QACnD,MAAM,EAAE,MAAM,CAAA;QACd,iEAAiE;QACjE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC5B,MAAM,EACF,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,0BAA0B,GAC1B,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAC3B,mBAAmB,GACnB,sBAAsB,CAAA;KAC3B,CAAC,CAAA;CACH"}
@@ -28,6 +28,7 @@ export function stripe(config) {
28
28
  },
29
29
  rewriteRequest(request, ctx) {
30
30
  const apiKey = ctx.apiKey ?? config.apiKey;
31
+ request.headers.delete('Stripe-Account');
31
32
  request.headers.set('Authorization', `Basic ${btoa(`${apiKey}:`)}`);
32
33
  return request;
33
34
  },
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../../src/proxy/services/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CAAC,MAAqB;IAC1C,OAAO,OAAO,CAAC,IAAI,CAAgB,QAAQ,EAAE;QAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,wBAAwB;QACnD,UAAU,EAAE,CAAC,UAAU,CAAC;QACxB,WAAW,EAAE,6DAA6D;QAC1E,IAAI,EAAE;YACJ,YAAY,EAAE,6BAA6B;YAC3C,QAAQ,EAAE,yBAAyB;YACnC,IAAI,EAAE,kCAAkC;SACzC;QACD,cAAc,CAAC,OAAO,EAAE,GAAG;YACzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAA;YAC1C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;YACnE,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../../src/proxy/services/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CAAC,MAAqB;IAC1C,OAAO,OAAO,CAAC,IAAI,CAAgB,QAAQ,EAAE;QAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,wBAAwB;QACnD,UAAU,EAAE,CAAC,UAAU,CAAC;QACxB,WAAW,EAAE,6DAA6D;QAC1E,IAAI,EAAE;YACJ,YAAY,EAAE,6BAA6B;YAC3C,QAAQ,EAAE,yBAAyB;YACnC,IAAI,EAAE,kCAAkC;SACzC;QACD,cAAc,CAAC,OAAO,EAAE,GAAG;YACzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAA;YAC1C,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;YACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;YACnE,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAA;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mppx",
3
3
  "type": "module",
4
- "version": "0.6.8",
4
+ "version": "0.6.9",
5
5
  "main": "./dist/index.js",
6
6
  "license": "MIT",
7
7
  "files": [
@@ -81,6 +81,49 @@ describe('stripe', () => {
81
81
  expect(receipt.method).toBe('tempo')
82
82
  })
83
83
 
84
+ test('security: strips caller-supplied Stripe-Account header before proxying', async () => {
85
+ upstreamServer = await Http.createServer((req, res) => {
86
+ res.writeHead(200, { 'Content-Type': 'application/json' })
87
+ res.end(
88
+ JSON.stringify({
89
+ headers: {
90
+ authorization: req.headers.authorization,
91
+ stripeAccount: req.headers['stripe-account'],
92
+ },
93
+ }),
94
+ )
95
+ })
96
+
97
+ const proxy = ApiProxy.create({
98
+ services: [
99
+ stripe({
100
+ apiKey,
101
+ baseUrl: upstreamServer.url,
102
+ routes: {
103
+ 'POST /v1/charges': true,
104
+ },
105
+ }),
106
+ ],
107
+ })
108
+ proxyServer = await Http.createServer(proxy.listener)
109
+
110
+ const res = await fetch(`${proxyServer.url}/stripe/v1/charges`, {
111
+ method: 'POST',
112
+ headers: {
113
+ 'Content-Type': 'application/x-www-form-urlencoded',
114
+ 'Stripe-Account': 'acct_123',
115
+ },
116
+ body: 'amount=100&currency=usd',
117
+ })
118
+ expect(res.status).toBe(200)
119
+
120
+ const body = (await res.json()) as {
121
+ headers: { authorization: string; stripeAccount?: string | string[] | undefined }
122
+ }
123
+ expect(body.headers.authorization).toBe(`Basic ${btoa(`${apiKey}:`)}`)
124
+ expect(body.headers.stripeAccount).toBeUndefined()
125
+ })
126
+
84
127
  test('behavior: returns 402 without credential', async () => {
85
128
  upstreamServer = await Http.createServer((_req, res) => {
86
129
  res.writeHead(200, { 'Content-Type': 'application/json' })
@@ -29,6 +29,7 @@ export function stripe(config: stripe.Config) {
29
29
  },
30
30
  rewriteRequest(request, ctx) {
31
31
  const apiKey = ctx.apiKey ?? config.apiKey
32
+ request.headers.delete('Stripe-Account')
32
33
  request.headers.set('Authorization', `Basic ${btoa(`${apiKey}:`)}`)
33
34
  return request
34
35
  },