mirror of
https://code.forgejo.org/actions/checkout.git
synced 2026-08-27 20:44:58 -04:00
Escape single quotes in submodule Foreach shell commands
This commit is contained in:
parent
f548e57e54
commit
3a65af85aa
5 changed files with 143 additions and 6 deletions
|
|
@ -67,6 +67,7 @@ describe('git-auth-helper tests', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
githubServerUrl = ''
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -664,6 +665,59 @@ describe('git-auth-helper tests', () => {
|
|||
}
|
||||
)
|
||||
|
||||
const configureSubmoduleAuth_escapesSingleQuotesInServerUrl =
|
||||
'configureSubmoduleAuth escapes single quotes in serverUrl to prevent command injection'
|
||||
it(configureSubmoduleAuth_escapesSingleQuotesInServerUrl, async () => {
|
||||
// Arrange: URL containing percent-encoded single quote (%27) which URL decoding expands to literal single quote
|
||||
githubServerUrl = 'https://evil%27$(id)host.com'
|
||||
await setup(configureSubmoduleAuth_escapesSingleQuotesInServerUrl)
|
||||
settings.githubServerUrl = githubServerUrl
|
||||
settings.persistCredentials = true
|
||||
settings.sshKey = ''
|
||||
settings.workflowOrganizationId = undefined
|
||||
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
||||
await authHelper.configureAuth()
|
||||
const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any>
|
||||
mockSubmoduleForeach.mockClear()
|
||||
|
||||
// Act
|
||||
await authHelper.configureSubmoduleAuth()
|
||||
|
||||
// Assert
|
||||
// Call 0: removeSubmoduleGitConfig for insteadOfKey
|
||||
// Call 1: insteadOf configuration
|
||||
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(2)
|
||||
const unsetCommand = mockSubmoduleForeach.mock.calls[0][0] as string
|
||||
expect(unsetCommand).toContain("'\\''")
|
||||
|
||||
const addCommand = mockSubmoduleForeach.mock.calls[1][0] as string
|
||||
expect(addCommand).toBe(
|
||||
"git config --local --add 'url.https://evil'\\''$(id)host.com/.insteadOf' 'git@evil'\\''$(id)host.com:'"
|
||||
)
|
||||
})
|
||||
|
||||
const removeAuth_escapesSingleQuotesInConfigKey =
|
||||
'removeAuth removes token from submodules escaping single quotes'
|
||||
it(removeAuth_escapesSingleQuotesInConfigKey, async () => {
|
||||
// Arrange
|
||||
githubServerUrl = 'https://evil%27$(id)host.com'
|
||||
await setup(removeAuth_escapesSingleQuotesInConfigKey)
|
||||
settings.githubServerUrl = githubServerUrl
|
||||
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
||||
await authHelper.configureAuth()
|
||||
const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any>
|
||||
mockSubmoduleForeach.mockClear()
|
||||
|
||||
// Act
|
||||
await authHelper.removeAuth()
|
||||
|
||||
// Assert: removeSubmoduleGitConfig should have been called for SSH_COMMAND_KEY and tokenConfigKey
|
||||
const calls = mockSubmoduleForeach.mock.calls.map(c => c[0] as string)
|
||||
const tokenCleanupCall = calls.find(c => c.includes('extraheader'))
|
||||
expect(tokenCleanupCall).toBeDefined()
|
||||
expect(tokenCleanupCall).toContain("'\\''")
|
||||
})
|
||||
|
||||
const removeAuth_removesSshCommand = 'removeAuth removes SSH command'
|
||||
it(removeAuth_removesSshCommand, async () => {
|
||||
if (!sshPath) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue