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

feat: add SecRequestBodyJsonDepthLimit directive #1110

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

fzipi
Copy link
Member

@fzipi fzipi commented Jul 21, 2024

what

  • add support for SecRequestBodyJsonDepthLimit
  • set default to 1024
  • validate JSON before parsing

why

  • prevent DoS with deeply created objects
  • better accuracy when matching json args, as it is now valid before parsing

@fzipi fzipi added the enhancement New feature or request label Jul 21, 2024
@fzipi fzipi requested a review from a team as a code owner July 21, 2024 14:42
internal/bodyprocessors/json.go Outdated Show resolved Hide resolved
internal/bodyprocessors/json.go Outdated Show resolved Hide resolved
@fzipi fzipi force-pushed the feat/SecRequestBodyJsonDepthLimit branch from 7661bcb to d176401 Compare July 21, 2024 14:47
readItems(json, key, res)
return res, nil

if !gjson.Valid(s.String()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need to do this? the first impression is this is very expensive, the second one is when we use a low body limit this will always be invalid isn't/

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not very expensive. Of course, it is more expensive than not doing vlaidation (adds roughly 33% more time in my benchmarks).

The upstream library says that If you are consuming JSON from an unpredictable source then you may want to validate prior to using GJSON. I agree, for the case of a WAF.

Or we can forget about validation, and see if someone can bypass us. 🤷 If we do, we should document clearly this decision that we prefer speed over security here.

@@ -77,7 +90,11 @@ func readItems(json gjson.Result, objKey []byte, res map[string]string) {
var val string
switch value.Type {
case gjson.JSON:
readItems(value, objKey, res)
// call recursively with one less item to avoid doing infinite recursion
iterationError = readItems(value, objKey, maxRecursion-1, res)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be if maxRecursion == -1 { return maxRecursion } else { return maxRecursion -1 }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readItems func is called always with the maxRecursion value > 0. Then each iteration will decrement this value. I'm not following your question :/

@@ -31,7 +34,7 @@ func (js *jsonBodyProcessor) ProcessRequest(reader io.Reader, v plugintypes.Tran

func (js *jsonBodyProcessor) ProcessResponse(reader io.Reader, v plugintypes.TransactionVariables, _ plugintypes.BodyProcessorOptions) error {
col := v.ResponseArgs()
data, err := readJSON(reader)
data, err := readJSON(reader, ResponseBodyRecursionLimit)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should never be -1 and always force a limit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we are assuming we don't trust the downstream service neither?

The directive takes into account that the request might be crafted so it creates a DoS of some kind on the body processor (as it happened in ModSecurity). Will the response value be configurable, and different from the request?

@fzipi fzipi requested a review from jcchavezs July 27, 2024 13:27
Signed-off-by: Felipe Zipitria <[email protected]>
@fzipi
Copy link
Member Author

fzipi commented Aug 2, 2024

ping @jcchavezs

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

Successfully merging this pull request may close these issues.

2 participants