Skip to content

Commit

Permalink
Merge pull request #393 from MrHohn/security-policy-checkresponse
Browse files Browse the repository at this point in the history
Implement security policy validator for real
  • Loading branch information
nicksardo authored Jul 11, 2018
2 parents 2683a0b + 9f87dd1 commit 2facce1
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
50 changes: 49 additions & 1 deletion pkg/fuzz/features/security_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ limitations under the License.
package features

import (
"context"
"fmt"
"net/http"

"k8s.io/api/extensions/v1beta1"
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"

"k8s.io/ingress-gce/pkg/annotations"
"k8s.io/ingress-gce/pkg/fuzz"
)

Expand Down Expand Up @@ -63,7 +68,50 @@ func (v *securityPolicyValidator) ConfigureAttributes(env fuzz.ValidatorEnv, ing

// CheckResponse implements fuzz.FeatureValidator.
func (v *securityPolicyValidator) CheckResponse(host, path string, resp *http.Response, body []byte) (fuzz.CheckResponseAction, error) {
// There isn't anything interesting to check in response.
backendConfig, err := fuzz.BackendConfigForPath(host, path, v.ing, v.env)
if err != nil {
if err == annotations.ErrBackendConfigAnnotationMissing {
// Don't fail this test if the service associated
// with the host + path has no BackendConfig annotation.
return fuzz.CheckResponseContinue, nil
}
return fuzz.CheckResponseContinue, err
}
if backendConfig.Spec.SecurityPolicy == nil || backendConfig.Spec.SecurityPolicy.Name == "" {
// Don't check on response if security policy isn't configured
// in BackendConfig or is set to none.
return fuzz.CheckResponseContinue, nil
}

policy, err := v.env.Cloud().BetaSecurityPolicies().Get(context.Background(), meta.GlobalKey(backendConfig.Spec.SecurityPolicy.Name))
if err != nil {
return fuzz.CheckResponseContinue, fmt.Errorf("error getting security policy %q: %v", backendConfig.Spec.SecurityPolicy.Name, err)
}
// Check for the exact response code we are expecting.
// For simplicity, the test assumes only the default rule exists.
if len(policy.Rules) == 0 {
return fuzz.CheckResponseContinue, fmt.Errorf("found 0 rule for security policy %q", backendConfig.Spec.SecurityPolicy.Name)
}
var expectedCode int
switch policy.Rules[0].Action {
case "allow":
expectedCode = 200
case "deny(403)":
expectedCode = 403
case "deny(404)":
expectedCode = 404
case "deny(502)":
expectedCode = 502
default:
return fuzz.CheckResponseContinue, fmt.Errorf("unrecognized rule %q", policy.Rules[0].Action)
}
if resp.StatusCode != expectedCode {
return fuzz.CheckResponseContinue, fmt.Errorf("unexpected status code %d, want %d", resp.StatusCode, expectedCode)
}
// Skip standard check in case of deny policy.
if expectedCode != 200 {
return fuzz.CheckResponseSkip, nil
}
return fuzz.CheckResponseContinue, nil
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/fuzz/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ func ServiceMapFromIngress(ing *v1beta1.Ingress) ServiceMap {
for _, path := range rule.HTTP.Paths {
hp := HostPath{Host: rule.Host, Path: path.Path}
if _, ok := ret[hp]; !ok {
ret[hp] = &path.Backend
// Copy the value over to a new struct so that we won't be
// saving the same pointer.
cloneBackend := path.Backend
ret[hp] = &cloneBackend
}
}
}
Expand Down

0 comments on commit 2facce1

Please sign in to comment.