Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[security] Path parser inconsistency could lead to bypass several security checks in emicklei/go-restful #497

Closed
JamieSlome opened this issue May 30, 2022 · 18 comments

Comments

@JamieSlome
Copy link

Reported via huntr.dev here.

Created: May 28th 2022

Description

There is a inconsistency between how golang(and other packages) and go-restful parses url path. This incosistency could lead several security check bypass in a complex system.

Steps to reproduce

Copy and run the code below

package main

import (
    "fmt"
    "html"
    "log"
    "net/http"
)

func main() {

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
    })

// If a user request matches with this path then it will be checked and if it didn't match then the request will be directly forwarded to the go-restful server.
    http.HandleFunc("/users/id_will_be_here", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info")
    })

    log.Fatal(http.ListenAndServe(":8081", nil))

}

Now If you send a request to the http://localhost:8081/users/id_will_be_here then you will get a hit to the expected endpoint and it will check the authorization part
Now if you send a request to the http://localhost:8081/users/id_will_be_here/ (notice the extra / in last) then this server won't process this request as the path name doesn't match but the problem is that go-restful treat this path and the previous as same.
So this inconsistency could lead some issues in this scenerio as the first sever wont check the security checks but the second server(go-restful) will return user data.

Impact

Security check bypass

Occurrences

web_service.go L80

@emicklei
Copy link
Owner

emicklei commented Jun 2, 2022

Thank you for reporting this. I will investigate this further.

@emicklei
Copy link
Owner

emicklei commented Jun 4, 2022

i was able to reproduce this issue.

your example output

~/tmp/issue497
$ curl http://localhost:8081/users/id_will_be_here
I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info

emicklei@Ernests-iMac-10 on Sat Jun 04 at 10:35 AM
~/tmp/issue497
$ curl http://localhost:8081/users/id_will_be_here/
Hello, "/users/id_will_be_here/"

go-restful example:

package main

import (
	"fmt"
	"html"
	"log"
	"net/http"

	restful "github.com/emicklei/go-restful/v3"
)

func main() {
	ws := new(restful.WebService)
	ws.Route(ws.GET("/").To(hello))
	ws.Route(ws.GET("/users/id_will_be_here").To(check))
	restful.Add(ws)
	log.Fatal(http.ListenAndServe(":8081", nil))
}

func hello(req *restful.Request, resp *restful.Response) {
	fmt.Fprintf(resp, "Hello, %q", html.EscapeString(req.Request.URL.Path))
}

func check(req *restful.Request, resp *restful.Response) {
	fmt.Fprintf(resp, "I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info")
}

go-restful output:

~/tmp/issue497
$ curl http://localhost:8081/users/id_will_be_here/
I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info

emicklei@Ernests-iMac-10 on Sat Jun 04 at 10:39 AM
~/tmp/issue497
$ curl http://localhost:8081/users/id_will_be_here
I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info

@emicklei
Copy link
Owner

emicklei commented Jun 4, 2022

here, the slash is trimmed

return strings.Split(strings.Trim(path, "/"), "/")

now the problem is that change this code will break existing behavior ; client of the package may be affected negatively.
So I am thinking about added a feature flag to disable the trimming and by default this is set to false. Only when it is explicitly set to true then the behavior is conform the standard route matching. This of course need to be documented.

@starzhanganz
Copy link

starzhanganz commented Sep 19, 2022

@emicklei May I know any update on this? As OTEL has used this package, it's affecting many other users using OTEL images. thanks!
OTEL Link

Report from Security scanning tools:
github.com/emicklei/go-restful/v3 module from all versions is vulnerable to Authentication Bypass by Primary Weakness. There is an inconsistency in how go-restful parses URL paths. This inconsistency could lead several security check bypass in a complex system.

@codechris1
Copy link

Hello guys,

Is there any update on this?

@emicklei
Copy link
Owner

hi all, sorry for the delay. I will add this feature flag as mentioned. Will that suffice?

@emicklei
Copy link
Owner

After the change, two test fail. Need to check if the test was correct in the first place

--- FAIL: Test_matchesRouteByPathTokens (0.00s)
--- FAIL: TestMatchesPath_VarOnFront (0.00s)

@emicklei
Copy link
Owner

please check #511

@emicklei
Copy link
Owner

emicklei commented Oct 3, 2022

@JamieSlome i believe the PR will fix the reported issue

@JamieSlome
Copy link
Author

@benharvie

@starzhanganz
Copy link

Looks like the PR is still not merged yet, probably due to the code test coverage filed?
Appreciate any update on this!

@dvasilen
Copy link

dvasilen commented Nov 3, 2022

PRISMA-2022-0227. The fix or an ETA is appreciated.

@jnewfield
Copy link

Should this PR be closed since PR #511 has been merged?

@jimmyseto
Copy link

PRISMA-2022-0227. The fix or an ETA is appreciated.

hi. did the fix for this issue address PRISMA-2022-0227? a scan against v3.10.1 suggests the vulnerability is still here (?).

@brutif
Copy link

brutif commented Nov 22, 2022

I'm not sure this is a bypass. Yes, go-restful handles trailing slashes differently than net/http, but how could a bypass realistically occur? From above go-restful example,


// called from ws.Route(ws.GET("/users/id_will_be_here").To(check))
func check(req *restful.Request, resp *restful.Response) {
	fmt.Fprintf(resp, "I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info")
}

The presence or absence of the trailing / won't cause the authorization check to be skipped, or the wrong route to be selected. I'm trying to think of a realistic example where it would, and I can't.

carolynvs added a commit to carolynvs/porter-operator that referenced this issue Dec 13, 2022
This addresses PRISMA-2022-0227 which has no entry anywhere useful on the internet but is reported by IronBank. It has a fix for emicklei/go-restful#497.

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
wheatevo added a commit to wheatevo/flannel that referenced this issue Mar 24, 2023
Updates the go-restful dependency from version 3.8.0 to 3.10.2 to
address the following:

emicklei/go-restful#497
spilchen pushed a commit to spilchen/vertica-kubernetes that referenced this issue May 12, 2023
Upgrading go-restful package from 3.9.0 to 3.10.0 to address
[PRISMA-2022-0227](emicklei/go-restful#497)
@sam-trace
Copy link

Is there a CVE assigned to this bug?

@eastebry
Copy link

eastebry commented Mar 26, 2024

Hey @emicklei - sorry to resurrect an old issue, but there has been a surprising amount of noise in the Go community around this - particularly due to the fact that Prisma cloud is reporting this as a high severity issue and the decision to not upgrade this dependency by some members of the k8s community (which I personally think is quite reasonable).

I'm in agreement with @brutif above, I'm struggling to see how this bug would ever constitute a security vulnerability. Barring a very bespoke authorization system, I can't imagine a situation in which this issue could reasonably be considered a vulnerability. The code example provided in this issue feels contrived, and to me only demonstrates unusual/unexpected behavior. It takes quite a leap of logic to consider that behavior to be a security vulnerability, in my opinion.

I'm wondering, as the maintainer of this project, do you consider this to be a valid vulnerability? If you do not think it is, and are willing to indicate so publicly in this issue, I'd be happy to open a case with Palo Alto to see if we can have the prisma-2022-0227 vulnerability removed from their database.

Thank you!

@emicklei
Copy link
Owner

hi @eastebry , thank you for notifying me about this ongoing discussion. I need to spent some time on reading the status and reasons for not upgrading (btw the breaking change was reverted in a later release). I will get back to this issue later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants