Merge pull request #27 from actions/redirect-auth-issue
Redirects should not pass authorization to different domain
This commit is contained in:
@@ -179,6 +179,52 @@ describe('basics', () => {
|
|||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('does not pass auth with diff hostname redirects', async done => {
|
||||||
|
let headers = {
|
||||||
|
accept: 'application/json',
|
||||||
|
authorization: 'shhh'
|
||||||
|
}
|
||||||
|
let res: httpm.HttpClientResponse = await _http.get(
|
||||||
|
'https://httpbin.org/redirect-to?url=' +
|
||||||
|
encodeURIComponent('https://www.httpbin.org/get'),
|
||||||
|
headers
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.message.statusCode).toBe(200)
|
||||||
|
let body: string = await res.readBody()
|
||||||
|
let obj: any = JSON.parse(body)
|
||||||
|
// httpbin "fixes" the casing
|
||||||
|
expect(obj.headers['Accept']).toBe('application/json')
|
||||||
|
expect(obj.headers['Authorization']).toBeUndefined()
|
||||||
|
expect(obj.headers['authorization']).toBeUndefined()
|
||||||
|
expect(obj.url).toBe('https://www.httpbin.org/get')
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not pass Auth with diff hostname redirects', async done => {
|
||||||
|
let headers = {
|
||||||
|
Accept: 'application/json',
|
||||||
|
Authorization: 'shhh'
|
||||||
|
}
|
||||||
|
let res: httpm.HttpClientResponse = await _http.get(
|
||||||
|
'https://httpbin.org/redirect-to?url=' +
|
||||||
|
encodeURIComponent('https://www.httpbin.org/get'),
|
||||||
|
headers
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.message.statusCode).toBe(200)
|
||||||
|
let body: string = await res.readBody()
|
||||||
|
let obj: any = JSON.parse(body)
|
||||||
|
// httpbin "fixes" the casing
|
||||||
|
expect(obj.headers['Accept']).toBe('application/json')
|
||||||
|
expect(obj.headers['Authorization']).toBeUndefined()
|
||||||
|
expect(obj.headers['authorization']).toBeUndefined()
|
||||||
|
expect(obj.url).toBe('https://www.httpbin.org/get')
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
it('does basic head request', async done => {
|
it('does basic head request', async done => {
|
||||||
let res: httpm.HttpClientResponse = await _http.head(
|
let res: httpm.HttpClientResponse = await _http.head(
|
||||||
'http://httpbin.org/get'
|
'http://httpbin.org/get'
|
||||||
|
|||||||
10
index.ts
10
index.ts
@@ -386,6 +386,16 @@ export class HttpClient {
|
|||||||
// which will leak the open socket.
|
// which will leak the open socket.
|
||||||
await response.readBody()
|
await response.readBody()
|
||||||
|
|
||||||
|
// strip authorization header if redirected to a different hostname
|
||||||
|
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
|
||||||
|
for (let header in headers) {
|
||||||
|
// header names are case insensitive
|
||||||
|
if (header.toLowerCase() === 'authorization') {
|
||||||
|
delete headers[header]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// let's make the request with the new redirectUrl
|
// let's make the request with the new redirectUrl
|
||||||
info = this._prepareRequest(verb, parsedRedirectUrl, headers)
|
info = this._prepareRequest(verb, parsedRedirectUrl, headers)
|
||||||
response = await this.requestRaw(info, data)
|
response = await this.requestRaw(info, data)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/http-client",
|
"name": "@actions/http-client",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"description": "Actions Http Client",
|
"description": "Actions Http Client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user