forked from mirror/gjson
Limit the complexity of "like" queries that match on a pattern.
This commit adds the uses the MatchLimit function, which it the same as Match but will limit the complexity of the input pattern. This is to avoid long running matches, specifically to avoid ReDos attacks from arbritary inputs.
This commit is contained in:
parent
590010fdac
commit
77a57fda87
17
gjson.go
17
gjson.go
|
@ -1089,9 +1089,9 @@ func parseObject(c *parseContext, i int, path string) (int, bool) {
|
||||||
}
|
}
|
||||||
if rp.wild {
|
if rp.wild {
|
||||||
if kesc {
|
if kesc {
|
||||||
pmatch = match.Match(unescape(key), rp.part)
|
pmatch = matchLimit(unescape(key), rp.part)
|
||||||
} else {
|
} else {
|
||||||
pmatch = match.Match(key, rp.part)
|
pmatch = matchLimit(key, rp.part)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if kesc {
|
if kesc {
|
||||||
|
@ -1176,6 +1176,15 @@ func parseObject(c *parseContext, i int, path string) (int, bool) {
|
||||||
}
|
}
|
||||||
return i, false
|
return i, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// matchLimit will limit the complexity of the match operation to avoid ReDos
|
||||||
|
// attacks from arbritary inputs.
|
||||||
|
// See the github.com/tidwall/match.MatchLimit function for more information.
|
||||||
|
func matchLimit(str, pattern string) bool {
|
||||||
|
matched, _ := match.MatchLimit(str, pattern, 10000)
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
func queryMatches(rp *arrayPathResult, value Result) bool {
|
func queryMatches(rp *arrayPathResult, value Result) bool {
|
||||||
rpv := rp.query.value
|
rpv := rp.query.value
|
||||||
if len(rpv) > 0 && rpv[0] == '~' {
|
if len(rpv) > 0 && rpv[0] == '~' {
|
||||||
|
@ -1213,9 +1222,9 @@ func queryMatches(rp *arrayPathResult, value Result) bool {
|
||||||
case ">=":
|
case ">=":
|
||||||
return value.Str >= rpv
|
return value.Str >= rpv
|
||||||
case "%":
|
case "%":
|
||||||
return match.Match(value.Str, rpv)
|
return matchLimit(value.Str, rpv)
|
||||||
case "!%":
|
case "!%":
|
||||||
return !match.Match(value.Str, rpv)
|
return !matchLimit(value.Str, rpv)
|
||||||
}
|
}
|
||||||
case Number:
|
case Number:
|
||||||
rpvn, _ := strconv.ParseFloat(rpv, 64)
|
rpvn, _ := strconv.ParseFloat(rpv, 64)
|
||||||
|
|
|
@ -2024,6 +2024,11 @@ func TestVariousFuzz(t *testing.T) {
|
||||||
testJSON = `[#.@pretty.@join:{""[]""preserve"3,"][{]]]`
|
testJSON = `[#.@pretty.@join:{""[]""preserve"3,"][{]]]`
|
||||||
Get(testJSON, testJSON)
|
Get(testJSON, testJSON)
|
||||||
|
|
||||||
|
// Issue #237
|
||||||
|
testJSON1 := `["*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,,,,,,"]`
|
||||||
|
testJSON2 := `#[%"*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,,,,,,""*,*"]`
|
||||||
|
Get(testJSON1, testJSON2)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubpathsWithMultipaths(t *testing.T) {
|
func TestSubpathsWithMultipaths(t *testing.T) {
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -3,6 +3,6 @@ module github.com/tidwall/gjson
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/tidwall/match v1.1.0
|
github.com/tidwall/match v1.1.1
|
||||||
github.com/tidwall/pretty v1.2.0
|
github.com/tidwall/pretty v1.2.0
|
||||||
)
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1,4 +1,4 @@
|
||||||
github.com/tidwall/match v1.1.0 h1:VfI2e2aXLvytih7WUVyO9uvRC+RcXlaTrMbHuQWnFmk=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/match v1.1.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
|
Loading…
Reference in New Issue