# Security-focused QA and retesting

Go beyond the happy path: verify denial, outage, race and side-effect behavior. Define expectations independently of current implementation.

Original AI-assisted SecNet educational content. Fictional local examples; not a standards provider publication, endorsement or compliance evidence. Page exercises do not create account progress.

Sources checked: 2026-10-21

## Matrix and test oracle

The expected result is the test oracle. Copying current behavior into expectations preserves bugs. Select dimensions for actor, tenant, operation, resource existence and session state. Check more than a denial status: verify unchanged data, version and external effects afterward. Retain permitted cases; denying everything is not a secure and functional solution.

## Failure modes and races

Malformed JSON, oversized bodies or identity-provider outage must not expand access. Errors need controlled user responses and traceable operational records without secrets or personal data. Start two same-version requests together and assert the single-winner invariant. Network retries and external calls require additional idempotency design.

## Retest scope

Repeating the original reproduction is necessary but insufficient. Test a variant, an alternate access path and legitimate use. Control fixture data and time dependencies rather than claiming success from arbitrary repetitions. Store automated results with the tested revision. A passing local fixture does not verify the real product, browser or mobile device.

## Example retest package

A permission-fix retest package should include four core outcomes: permitted read 200; other-user/tenant reads 404; anonymous read 401; unchanged data after a denied update. Add stale-version writes, oversized bodies and wrong CSRF cases. Checking status alone cannot establish data integrity, which is why the actual HTTP fixture rereads title and version. A fix that denies all access can pass negative tests while breaking legitimate use; the permitted case catches that. Record command, revision and synthetic dataset, and clearly identify platform tests that were not performed.

## Working sequence

1. Define invariants independently of code.
2. Prepare permitted and negative matrices.
3. Add outage and race scenarios.
4. Compare side effects before and after.
5. Close retesting with revision and evidence.

## 1. Only the happy path

A normal read test does not cover other-user, other-tenant and anonymous access. The model requires all three denial checks.

This code is a local policy model; it does not replace target/device testing.

### Weak implementation
```js
s=>s.happyPathPassed
```

### Corrected implementation
```js
s=>s.happyPathPassed&&s.otherUserDenied&&s.otherTenantDenied&&s.anonymousDenied
```

### Synthetic input and actual model output
```json
{
  "before": [
    {
      "name": "happy-only",
      "input": {
        "happyPathPassed": true,
        "otherUserDenied": false,
        "otherTenantDenied": false,
        "anonymousDenied": false
      },
      "expected": false,
      "observed": true,
      "matched": false
    },
    {
      "name": "negative-matrix",
      "input": {
        "happyPathPassed": true,
        "otherUserDenied": true,
        "otherTenantDenied": true,
        "anonymousDenied": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    }
  ],
  "after": [
    {
      "name": "happy-only",
      "input": {
        "happyPathPassed": true,
        "otherUserDenied": false,
        "otherTenantDenied": false,
        "anonymousDenied": false
      },
      "expected": false,
      "observed": false,
      "matched": true
    },
    {
      "name": "negative-matrix",
      "input": {
        "happyPathPassed": true,
        "otherUserDenied": true,
        "otherTenantDenied": true,
        "anonymousDenied": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    }
  ]
}
```

## 2. Dependency failure

Healthy-dependency testing does not prove failure policy. Test denial during parsing and identity failures and absence of side effects after denial.

This code is a local policy model; it does not replace target/device testing.

### Weak implementation
```js
s=>s.dependenciesGreen
```

### Corrected implementation
```js
s=>s.dependenciesGreen&&s.parserFailureDenied&&s.authOutageDenied&&s.noSideEffectOnDenial
```

### Synthetic input and actual model output
```json
{
  "before": [
    {
      "name": "healthy-only",
      "input": {
        "dependenciesGreen": true,
        "parserFailureDenied": false,
        "authOutageDenied": false,
        "noSideEffectOnDenial": false
      },
      "expected": false,
      "observed": true,
      "matched": false
    },
    {
      "name": "failure-tested",
      "input": {
        "dependenciesGreen": true,
        "parserFailureDenied": true,
        "authOutageDenied": true,
        "noSideEffectOnDenial": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    }
  ],
  "after": [
    {
      "name": "healthy-only",
      "input": {
        "dependenciesGreen": true,
        "parserFailureDenied": false,
        "authOutageDenied": false,
        "noSideEffectOnDenial": false
      },
      "expected": false,
      "observed": false,
      "matched": true
    },
    {
      "name": "failure-tested",
      "input": {
        "dependenciesGreen": true,
        "parserFailureDenied": true,
        "authOutageDenied": true,
        "noSideEffectOnDenial": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    }
  ]
}
```

## 3. Two simultaneous requests

Single-request success does not prove race safety. Require CAS, a single write and no duplicate effect together. The actual HTTP fixture sends two same-version requests in parallel.

This code is a local policy model; it does not replace target/device testing.

### Weak implementation
```js
s=>s.singleRequestPassed
```

### Corrected implementation
```js
s=>s.singleRequestPassed&&s.casChecked&&s.onlyOneWrite&&s.noDuplicateEffect
```

### Synthetic input and actual model output
```json
{
  "before": [
    {
      "name": "single-only",
      "input": {
        "singleRequestPassed": true,
        "casChecked": false,
        "onlyOneWrite": false,
        "noDuplicateEffect": false
      },
      "expected": false,
      "observed": true,
      "matched": false
    },
    {
      "name": "concurrent-invariant",
      "input": {
        "singleRequestPassed": true,
        "casChecked": true,
        "onlyOneWrite": true,
        "noDuplicateEffect": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    }
  ],
  "after": [
    {
      "name": "single-only",
      "input": {
        "singleRequestPassed": true,
        "casChecked": false,
        "onlyOneWrite": false,
        "noDuplicateEffect": false
      },
      "expected": false,
      "observed": false,
      "matched": true
    },
    {
      "name": "concurrent-invariant",
      "input": {
        "singleRequestPassed": true,
        "casChecked": true,
        "onlyOneWrite": true,
        "noDuplicateEffect": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    }
  ]
}
```

## Exit evidence

- Test plan with independently defined expectations
- Same-revision retest and side-effect evidence

## References

- [OWASP ASVS 5.0.0](https://asvs.owasp.org/)
- [OWASP WSTG 4.2 stable](https://owasp.org/projects/web-security-testing-guide)
- [OWASP API Security Top 10 2023](https://api-security.owasp.org/editions/2023/en/0x11-t10/)
