Limit the length of logged HTTP response (#1778)
* Limit the length of logged HTTP response Fixes #1777 * Fix crash, add tests * Fix utf-8 truncation * move more logic into helper method * Add unit test for truncateBody https://github.com/letsencrypt/boulder/pull/1778
This commit is contained in:
parent
dc15f6a55e
commit
801626fb15
|
|
@ -373,8 +373,9 @@ func (va *ValidationAuthorityImpl) validateHTTP01(ctx context.Context, identifie
|
|||
}
|
||||
|
||||
if expectedKeyAuth != payload {
|
||||
truncBody := truncateBody(payload)
|
||||
errString := fmt.Sprintf("The key authorization file from the server did not match this challenge [%v] != [%v]",
|
||||
expectedKeyAuth, string(body))
|
||||
expectedKeyAuth, truncBody)
|
||||
va.log.Info(fmt.Sprintf("%s for %s", errString, identifier))
|
||||
return validationRecords, &probs.ProblemDetails{
|
||||
Type: probs.UnauthorizedProblem,
|
||||
|
|
@ -385,6 +386,19 @@ func (va *ValidationAuthorityImpl) validateHTTP01(ctx context.Context, identifie
|
|||
return validationRecords, nil
|
||||
}
|
||||
|
||||
// truncateBody will cut off a string at 45 UTF-8 characters.
|
||||
func truncateBody(str string) string {
|
||||
count := 0
|
||||
const max = 45
|
||||
for index, _ := range str {
|
||||
count++
|
||||
if count > max {
|
||||
return fmt.Sprintf("%s…", str[:index])
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func (va *ValidationAuthorityImpl) validateTLSSNI01(ctx context.Context, identifier core.AcmeIdentifier, challenge core.Challenge) ([]core.ValidationRecord, *probs.ProblemDetails) {
|
||||
if identifier.Type != "dns" {
|
||||
va.log.Info(fmt.Sprintf("Identifier type for TLS-SNI was not DNS: %s", identifier))
|
||||
|
|
|
|||
|
|
@ -541,6 +541,36 @@ func TestValidateHTTP(t *testing.T) {
|
|||
test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status)
|
||||
}
|
||||
|
||||
func TestValidateHTTPResponseDocument(t *testing.T) {
|
||||
chall := core.HTTPChallenge01(accountKey)
|
||||
setChallengeToken(&chall, core.NewToken())
|
||||
|
||||
hs := httpSrv(t, `a.StartOfLine.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.PastTruncationPoint.aaaaaaaaaaaaaaaaaaaa`)
|
||||
port, err := getPort(hs)
|
||||
test.AssertNotError(t, err, "failed to get test server port")
|
||||
stats, _ := statsd.NewNoopClient()
|
||||
va := NewValidationAuthorityImpl(&cmd.PortConfig{HTTPPort: port}, nil, nil, stats, clock.Default())
|
||||
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||
mockRA := &MockRegistrationAuthority{}
|
||||
va.RA = mockRA
|
||||
|
||||
defer hs.Close()
|
||||
|
||||
var authz = core.Authorization{
|
||||
ID: core.NewToken(),
|
||||
RegistrationID: 1,
|
||||
Identifier: ident,
|
||||
Challenges: []core.Challenge{chall},
|
||||
}
|
||||
va.validate(ctx, authz, 0)
|
||||
|
||||
test.AssertEquals(t, core.StatusInvalid, mockRA.lastAuthz.Challenges[0].Status)
|
||||
test.Assert(t, len(log.GetAllMatching("StartOfLine")) > 1, "Beginning of response body not logged")
|
||||
test.Assert(t, len(log.GetAllMatching("…")) > 1, "Ellipsis not logged")
|
||||
test.AssertEquals(t, len(log.GetAllMatching("PastTruncationPoint")), 0) // End of response body was logged
|
||||
|
||||
}
|
||||
|
||||
// challengeType == "tls-sni-00" or "dns-00", since they're the same
|
||||
func createChallenge(challengeType string) core.Challenge {
|
||||
chall := core.Challenge{
|
||||
|
|
@ -1008,6 +1038,27 @@ func TestCAAFailure(t *testing.T) {
|
|||
test.AssertEquals(t, core.StatusInvalid, mockRA.lastAuthz.Challenges[0].Status)
|
||||
}
|
||||
|
||||
func TestTruncateBody(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Case string
|
||||
Expected string
|
||||
}{
|
||||
{"", ""},
|
||||
{"a", "a"},
|
||||
{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
|
||||
{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…"},
|
||||
{"ááááááááááááááááááááááááááááááááááááááááááááá", "ááááááááááááááááááááááááááááááááááááááááááááá"},
|
||||
{"áááááááááááááááááááááááááááááááááááááááááááááá", "ááááááááááááááááááááááááááááááááááááááááááááá…"},
|
||||
}
|
||||
|
||||
for _, v := range testCases {
|
||||
result := truncateBody(v.Case)
|
||||
if result != v.Expected {
|
||||
t.Errorf("got %q, expected %q", result, v.Expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type MockRegistrationAuthority struct {
|
||||
lastAuthz *core.Authorization
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue