mirror of https://github.com/actions/toolkit
ensure no path traversal
parent
8d03fb4787
commit
e9005f7727
|
@ -121,6 +121,16 @@ const mockGetArtifactFailure = jest.fn(() => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const mockGetArtifactMalicious = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.push(fs.readFileSync(path.join(__dirname, 'fixtures', 'evil.zip')))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
describe('download-artifact', () => {
|
describe('download-artifact', () => {
|
||||||
describe('public', () => {
|
describe('public', () => {
|
||||||
beforeEach(setup)
|
beforeEach(setup)
|
||||||
|
@ -170,6 +180,53 @@ describe('download-artifact', () => {
|
||||||
expect(response.downloadPath).toBe(fixtures.workspaceDir)
|
expect(response.downloadPath).toBe(fixtures.workspaceDir)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should not allow path traversal from malicious artifacts', async () => {
|
||||||
|
const downloadArtifactMock = github.getOctokit(fixtures.token).rest
|
||||||
|
.actions.downloadArtifact as MockedDownloadArtifact
|
||||||
|
downloadArtifactMock.mockResolvedValueOnce({
|
||||||
|
headers: {
|
||||||
|
location: fixtures.blobStorageUrl
|
||||||
|
},
|
||||||
|
status: 302,
|
||||||
|
url: '',
|
||||||
|
data: Buffer.from('')
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetArtifactMalicious
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const response = await downloadArtifactPublic(
|
||||||
|
fixtures.artifactID,
|
||||||
|
fixtures.repositoryOwner,
|
||||||
|
fixtures.repositoryName,
|
||||||
|
fixtures.token
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(downloadArtifactMock).toHaveBeenCalledWith({
|
||||||
|
owner: fixtures.repositoryOwner,
|
||||||
|
repo: fixtures.repositoryName,
|
||||||
|
artifact_id: fixtures.artifactID,
|
||||||
|
archive_format: 'zip',
|
||||||
|
request: {
|
||||||
|
redirect: 'manual'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
expect(mockGetArtifactMalicious).toHaveBeenCalledWith(
|
||||||
|
fixtures.blobStorageUrl
|
||||||
|
)
|
||||||
|
expect(
|
||||||
|
fs.readFileSync(path.join(fixtures.workspaceDir, 'etc/hosts'), 'utf8')
|
||||||
|
).toEqual('foo')
|
||||||
|
expect(response.downloadPath).toBe(fixtures.workspaceDir)
|
||||||
|
})
|
||||||
|
|
||||||
it('should successfully download an artifact to user defined path', async () => {
|
it('should successfully download an artifact to user defined path', async () => {
|
||||||
const customPath = path.join(testDir, 'custom')
|
const customPath = path.join(testDir, 'custom')
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue