Skip to content

fix: send back 400 status code on bad requests#1

Merged
jahzielv merged 4 commits into
remove-path-setting-on-scep-handlerfrom
15635-scep-bad-reqs
Jan 11, 2024
Merged

fix: send back 400 status code on bad requests#1
jahzielv merged 4 commits into
remove-path-setting-on-scep-handlerfrom
15635-scep-bad-reqs

Conversation

@jahzielv
Copy link
Copy Markdown

Related issue: fleetdm/fleet#15635

  • Allow caller to set handler path on scepserver.MakeHTTPHandler
  • fix: return bad request errors when requests fail validation
  • feat: some tests

@roperzh roperzh requested review from a team and removed request for a team January 10, 2024 20:10
@roperzh
Copy link
Copy Markdown

roperzh commented Jan 10, 2024

sorry, I requested a review by accident.

Copy link
Copy Markdown

@mna mna left a comment

Choose a reason for hiding this comment

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

Looks great! Just some concerns about the new validations, to make sure it doesn't break what were previously (I think?) ignored/no-ops requests.

Comment thread cmd/scepserver/scepserver.go
Comment thread cmd/scepserver/scepserver.go
Comment thread server/transport.go Outdated
Comment thread server/transport.go
operation := r.URL.Query().Get("operation")
if len(operation) == 0 {
return nil, &BadRequestError{Message: "missing operation"}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Might be worth double-checking by @roperzh who's more familiar than I am with the macOS MDM flow - my concern is that this could generate errors from requests that currently succeeded (but presumably ignored/no-ops) if there was no operation?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

to be honest I had to go and look at the spec because I didn't know the answer to this.

from what I can see, some messages can have empty operations so +1 to remove this.

Copy link
Copy Markdown
Author

@jahzielv jahzielv Jan 10, 2024

Choose a reason for hiding this comment

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

Gotcha; fwiw, currently if you leave out the operation, fleet responds with a 500. Removing this code would revert back to that behavior. Should I instead update the code to allow empty operations? Ditto for an empty message (like here) cc @roperzh

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

currently if you leave out the operation, fleet responds with a 500.

Ah gotcha, yeah if it did generate an error previously, then the added validation makes sense to me. I thought this case might've been a successful no-op before.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think you're right about operation, taking a second look here:

https://github.com/fleetdm/scep/blob/3aa7a5a9d937a028c081e46f605c4a85fbcdadde/server/endpoint.go#L137-L149

just as a curiosity, I also see this:

Note that when used with HTTP POST, the only OPERATION possible is "PKIOperation", so many CAs don't check this value or even notice its absence

Comment thread server/transport.go
if op == "PKIOperation" {
if len(msg) == 0 {
return nil, &BadRequestError{Message: "missing PKIOperation message"}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Here too, since we're adding new validation, just to make sure that we're not erroring on what is possibly a valid request that was previously ignored?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

agreed on this one as well.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm thinking: what about clients that use POST? (in SCEP you use a single path, and can use GET or POST, all communications are handled by parameters)

wonder if we should add the check upstream so it works independent of the request method used?

https://github.com/fleetdm/scep/blob/3aa7a5a9d937a028c081e46f605c4a85fbcdadde/server/service.go#L75

Copy link
Copy Markdown
Author

@jahzielv jahzielv Jan 10, 2024

Choose a reason for hiding this comment

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

@roperzh oh, I didn't realize that was the case! yeah, if you can use POST or GET for PKIOperations, then we should check before here. I can update that.

Something like this?

func message(r *http.Request) ([]byte, error) {
	var msg string
	q := r.URL.Query()
	if _, ok := q["message"]; ok {
		msg = q.Get("message")
	}
	if len(msg) == 0 {
		return nil, &BadRequestError{Message: "missing PKIOperation message"}
	}
	switch r.Method {
	case "GET":
		op := q.Get("operation")
		if op == "PKIOperation" {
			msg2, err := url.PathUnescape(msg)
			if err != nil {
				return nil, &BadRequestError{Message: fmt.Sprintf("invalid PKIOperation message: %s", msg)}
			}

			decoded, err := base64.StdEncoding.DecodeString(msg2)
			if err != nil {
				return nil, &BadRequestError{Message: fmt.Sprintf("failed to base64 decode message: %s: %s", err.Error(), msg2)}
			}

			return decoded, nil
		}
		return []byte(msg), nil
	case "POST":
		return ioutil.ReadAll(io.LimitReader(r.Body, maxPayloadSize))
	default:
		return nil, errors.New("method not supported")
	}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jahzielv I think that won't do it for POST because the message comes in the request body 🤔

If it's just operation=PKIOperation we're worried about (which seems reasonable for now), what do you think about doing it in the service (link I pointed above)

if len(data) == 0 {
    // bad request!
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🤦 gotcha. yeah, needed a small update to another part of the code, but that works! updated @roperzh

Comment thread server/transport.go
}

// StatusCode implements the kithttp StatusCoder interface
func (e *BadRequestError) StatusCode() int { return http.StatusBadRequest }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

👍 Once we move this to the monorepo, we'll probably be able to reuse the error type from the service package, but for now this LGTM!

Comment thread server/transport_test.go
r := mux.NewRouter()
r.Handle("/scep", scepHandler)
server := httptest.NewServer(r)
teardown := func() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit, but if it doesn't fan out to too many changes, we can use t.Cleanup(func() {...}) instead of returning the teardown function, so the caller doesn't have to remember to defer that function call.

Copy link
Copy Markdown

@roperzh roperzh left a comment

Choose a reason for hiding this comment

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

Martin review covers everything, I just want to add a note to sanity check between you and @mna (as this is going to move to the monorepo soon)

  • fleetdm/fleet currently uses a branch in this repo named remove-path-setting-on-scep-handler
  • this PR contains the changes in remove-path-setting-on-scep-handler and targets main

anything works IMO, just wanted to make sure we're all on the same page

@jahzielv jahzielv changed the base branch from main to remove-path-setting-on-scep-handler January 10, 2024 20:40
@jahzielv jahzielv marked this pull request as ready for review January 10, 2024 22:39
Copy link
Copy Markdown

@roperzh roperzh left a comment

Choose a reason for hiding this comment

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

lgtm!

@jahzielv jahzielv merged commit 4df608a into remove-path-setting-on-scep-handler Jan 11, 2024
@jahzielv jahzielv deleted the 15635-scep-bad-reqs branch January 11, 2024 14:34
jahzielv added a commit to fleetdm/fleet that referenced this pull request Jan 11, 2024
> 📜 Related issue: #15635

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/` or
`orbit/changes/`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [x] Added/updated tests
- [x] Manual QA for all new/changed functionality

Tests were added in the scep repo:
mikermcneil/fleet-scep#1
georgekarrv pushed a commit to fleetdm/fleet that referenced this pull request Jan 12, 2024
> 📜 Related issue: #15635

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/` or
`orbit/changes/`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [x] Added/updated tests
- [x] Manual QA for all new/changed functionality

Tests were added in the scep repo:
mikermcneil/fleet-scep#1
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

Successfully merging this pull request may close these issues.

3 participants