Skip to content

Commit

Permalink
Merge pull request from GHSA-mfqj-f22m-gv8j
Browse files Browse the repository at this point in the history
Fix IDOR webhook get does not correctly authorize project
  • Loading branch information
gschueler committed Oct 1, 2021
2 parents f739c61 + 962b81a commit a3bdc06
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 1 deletion.
Expand Up @@ -88,7 +88,11 @@ class WebhookController {
sendJsonError("You do not have access to this resource")
return
}
render webhookService.getWebhookWithAuth(params.id) as JSON
def webhook = webhookService.getWebhookForProjectWithAuth(params.id, params.project)
if(!webhook){
return sendJsonError("Webhook not found", HttpServletResponse.SC_NOT_FOUND)
}
render webhook as JSON
}

def list() {
Expand Down
10 changes: 10 additions & 0 deletions grails-webhooks/grails-app/services/webhooks/WebhookService.groovy
Expand Up @@ -290,6 +290,13 @@ class WebhookService {
Webhook hook = Webhook.get(id.toLong())
getWebhookWithAuthAsMap(hook)
}
def getWebhookForProjectWithAuth(String id, String project) {
Webhook hook = getWebhookWithProject(id.toLong(), project)
if(!hook){
return null
}
getWebhookWithAuthAsMap(hook)
}

private Map getWebhookWithAuthAsMap(Webhook hook) {
AuthenticationToken authToken = rundeckAuthTokenManagerService.getToken(hook.authToken)
Expand All @@ -299,6 +306,9 @@ class WebhookService {
Webhook getWebhook(Long id) {
return Webhook.get(id)
}
Webhook getWebhookWithProject(Long id, String project) {
return Webhook.findByIdAndProject(id,project)
}

Webhook getWebhookByUuid(String uuid) {
return Webhook.findByUuid(uuid)
Expand Down
Expand Up @@ -24,6 +24,7 @@ import com.dtolabs.rundeck.plugins.webhook.DefaultWebhookResponder
import com.dtolabs.rundeck.plugins.webhook.WebhookDataImpl
import com.dtolabs.rundeck.plugins.webhook.WebhookResponder
import grails.testing.web.controllers.ControllerUnitTest
import org.rundeck.core.auth.AuthConstants
import spock.lang.Specification

import javax.servlet.http.HttpServletRequest
Expand Down Expand Up @@ -96,6 +97,32 @@ class WebhookControllerSpec extends Specification implements ControllerUnitTest<
0 * controller.webhookService.delete(_)
}

def "get webhook should fail when project param does not match webhook project"() {
given:
controller.webhookService = Mock(WebhookService) {
1 * getWebhookForProjectWithAuth('1234','otherproject')
}

controller.apiService = Mock(MockApiService)
controller.rundeckAuthContextEvaluator = Mock(AuthContextEvaluator)
controller.rundeckAuthContextProvider = Mock(AuthContextProvider)
when:
params.id = "1234"
params.project = 'otherproject'
controller.get()

then:
response.status==404
response.text == '{"err":"Webhook not found"}'
1 * controller.rundeckAuthContextProvider.getAuthContextForSubjectAndProject(_,'otherproject')
1 * controller.rundeckAuthContextEvaluator.authorizeProjectResourceAny(
_,
AuthConstants.RESOURCE_TYPE_WEBHOOK,
[AuthConstants.ACTION_ADMIN, AuthConstants.ACTION_READ],
'otherproject'
) >> true
}

def "503 if webhook is not enabled"() {
given:
controller.webhookService = Mock(MockWebhookService)
Expand Down
21 changes: 21 additions & 0 deletions grails-webhooks/src/test/groovy/webhooks/WebhookServiceSpec.groovy
Expand Up @@ -494,6 +494,27 @@ class WebhookServiceSpec extends Specification implements ServiceUnitTest<Webhoo
output.authToken == "abc123"
}

def "getWebhookForProjectWithAuth returns null for wrong project"() {
setup:
def project = 'aproject'
Webhook hook = new Webhook()
hook.name = "hit"
hook.project = "otherproject"
hook.authToken = "abc123"
hook.eventPlugin = "do-some-action"
hook.pluginConfigurationJson = '{"prop1":"true"}'
hook.save()

service.rundeckAuthTokenManagerService = Mock(AuthTokenManager)

when:
def output = service.getWebhookForProjectWithAuth(hook.id.toString(), project)

then:
output == null
0 * service.rundeckAuthTokenManagerService.getToken("abc123")
}

def "delete all webhooks in project"() {
setup:
String project = "prj1"
Expand Down

0 comments on commit a3bdc06

Please sign in to comment.