- Project: Apache Directory SCIMple — a Jakarta EE implementation of SCIM 2.0 (RFC 7642 / RFC 7643 / RFC 7644).
- Applies to: the SCIMple revision this file is committed with; each release's git tag binds its own copy (see Version binding).
- Date: 2026-05-30.
- Authors of this model: the Apache Directory PMC.
- Status: Draft, prepared by the Apache Directory PMC (2026-05-30). Not yet formally reviewed or ratified;
submitted for PMC review and endorsement via lazy consensus on
dev@directory.apache.org.
This threat model is versioned alongside the project. A vulnerability report filed against project version N is
triaged against this model as it stood at N, not as it stands at HEAD. Because the file lives in the repository,
the git tag for a release automatically binds that release's copy of the model — no separate snapshot process is
needed; the THREAT_MODEL.md at a release's tag is the model for that release. The
publication venue is the repository (canonical); SECURITY.md links to it.
- Findings that violate a property claimed in §8 should be reported privately
per
SECURITY.md(the ASF security process) — never via a public GitHub issue. - Findings that fall under §3 (out of scope) or §9 (disclaimed properties) will be closed citing this document; see the disposition table in §13.
Claims marked (documented: …) cite their source — code, a committed test, the README, or an RFC. All other statements are assertions by the PMC for this draft.
Apache Directory SCIMple is a set of embeddable Java libraries that let an application speak SCIM 2.0 — the standard
REST protocol for provisioning users and groups across identity systems. It is not a turnkey identity server. The
integrator brings their own persistence by implementing a Repository interface and their own deployment container
(Spring Boot, Quarkus, Jersey, a servlet container, …); SCIMple supplies the SCIM wire protocol, the schema/extension
model, the filter and PATCH expression parsers, the REST endpoint implementations, and an outbound SCIM client. The
libraries are published to Maven Central under org.apache.directory.scimple.
Primary intended use cases:
- In-process embedding of SCIM 2.0 server endpoints into a host application that supplies its own
Repositorypersistence and its own authentication layer. - In-process embedding of a SCIM 2.0 client to provision against a remote SCIM service.
- Use of the schema / spec libraries (resource models, filter parser, PATCH path parser) independently of either.
Deployment contexts: an embedded library inside a JVM application — delivered through Spring Boot, Quarkus, Jersey, or a Jakarta-EE servlet container. SCIMple does not run as a standalone daemon; the host owns the process, the listening socket, TLS termination, and the authentication boundary.
Caller roles. The server side is exposed over HTTP, so "caller" is not a single trust level:
| Role | Trust | Description |
|---|---|---|
SCIM client — an external caller of your scim-server (not the scim-client library) |
untrusted | Sends HTTP requests with attacker-controllable bodies, filter strings, PATCH paths, headers, and query params. |
| Integrator / operator | trusted | Writes the Repository implementation, wires the deployment, configures auth/TLS, registers schemas. Authoring this code = already inside the trust boundary. |
Remote SCIM peer (the server scim-client calls) |
trusted | The server an integrator points scim-client at — chosen by the integrator, who holds credentials for it and trusts it. A malicious or compromised remote server is out of scope (§3, §7). |
| Family | Representative entry point | Touches outside the process? | In model? |
|---|---|---|---|
| scim-spec-schema (parsing) | SCIM JSON models, ANTLR filter grammar, PATCH path parser, URN/@Urn validator |
No (pure parsing/validation) | In |
| scim-spec-protocol | REST protocol models (SearchRequest, BulkRequest, ErrorResponse), JAX-RS interfaces |
No | In |
| scim-core | Repository<T> SPI, SchemaRegistry, RepositoryRegistry, Jackson ObjectMapper/deserializer |
No | In (the SPI boundary is in model; integrator impls are out) |
| scim-server | JAX-RS endpoint impls: /Users, /Groups, /Bulk, /Me, /Schemas, /ResourceTypes, /ServiceProviderConfig, .search |
Inbound HTTP (via the host container) | In |
| scim-client | BaseScimClient and friends — outbound SCIM REST calls over a caller-supplied JAX-RS Client |
Outbound HTTP (via caller-supplied client) | In (integrator obligations only; the remote peer is trusted — §7) |
| support/spring-boot | scim-spring-boot-starter auto-configuration |
No (wiring only) | In (wiring) |
| scim-server-examples/, reference-projects/scim-server-ldap | demo apps (in-memory, Jersey, Quarkus, Spring Boot, LDAP) | Yes (open sockets, persist data) | Out — see §3 |
| scim-test, scim-tools, scim-compliance-tests, scim-coverage | test/CI tooling | varies (test only) | Out — see §3 |
Use cases the project does not aim to support:
- A complete, secure identity server out of the box. SCIMple supplies the SCIM protocol layer only; authentication, authorization, transport security, rate limiting, and persistence are the integrator's responsibility.
- A query/persistence engine. SCIMple parses SCIM filters into structured
FilterExpressiontrees and hands them to the integrator'sRepository; it does not translate them to SQL/LDAP/etc. (BaseFilterExpressionMapperis a helper for integrators who choose to, not a SCIMple-owned query builder).
Threats not defended against at this layer:
- Network-level attacks (TLS interception, traffic analysis) — the host terminates TLS.
- Authentication/authorization bypass — there is no SCIMple-owned authN/authZ to bypass (§8/§9); this is the integrator's layer.
- Abuse of legitimately-granted SCIM authority. SCIM is a high-privilege surface — a client authorized to create/modify/delete users and groups (and set passwords) already wields broad power over identities. A caller using granted authority to harmful effect (creating a rogue admin, mass-deleting, resetting a password) is performing an authorized operation; SCIMple executing it faithfully is correct behavior, not a vulnerability. Constraining what each authenticated client may do — least privilege, per-operation authorization — is the integrator's responsibility (§9, §10). This is distinct from subverting SCIMple's own machinery (crash, secret leak, injection past the parsed boundary), which SCIMple does defend regardless of caller privilege (§8).
- Attacks requiring control of the embedding process, the
Repository, the registered schemas, or the JAX-RSClient— that is trusted code (§7). - A malicious or compromised remote SCIM server that
scim-clientconnects to. The integrator chooses, trusts, and authenticates to that server;scim-clientis a library under the integrator's control, not an adversary-facing surface. SCIMple does not hardenscim-clientagainst hostile responses from the server it calls.
Code that ships in the repo but is out of this model:
scim-server-examples/**andreference-projects/scim-server-ldap— example/demo applications, not published to Maven Central (enforced: thescim-server-examplesparent pom setsmaven.deploy.skip/skipNexusStagingDeployMojo). They open sockets and store data (theInMemoryUserServiceexamples hold passwords in plaintext) and are not production-hardened. Findings here areOUT-OF-MODEL: unsupported-component(§13). The example READMEs carry a demo-only warning.scim-test,scim-tools,scim-compliance-tests,scim-coverage— test/CI tooling.
Where the boundary sits. The trust boundary is the HTTP/API surface of
scim-server — untrusted bytes cross into the process there. scim-client calls out to a server the integrator
chose and trusts (§7), so its outbound side is not
an adversarial trust boundary; the integrator owns its transport configuration (§9/§10).
Data flow (inbound request):
- Untrusted bytes arrive at a JAX-RS endpoint (
scim-server). The body is deserialized by Jackson into strongly-typed SCIM resource objects;filter/PATCHpathstrings are parsed by the ANTLR grammar intoFilterExpression/PatchOperationPathtrees. This is the parse step — the richest attack surface. - The endpoint resolves the target
RepositoryfromRepositoryRegistryand invokes it with already-parsed, structured objects — never the raw request strings. - The integrator's
Repository(trusted code) performs persistence and returns resources. - On the way out,
AttributeUtilstripsreturned = NEVERattributes (e.g.password) and applies attribute selection before serialization.
The key transition: untrusted text → structured object happens entirely inside SCIMple before any integrator code
runs. This is what makes the Repository SPI a clean boundary.
- scim-spec-schema (filter/PATCH/JSON parsing): in-model only if reachable from attacker-controlled input — a
filterquery string, a PATCHpath, or a request body. - scim-core (Repository SPI): in-model only if the issue is in SCIMple's marshaling/dispatch, not in the
integrator's
Repository. - scim-server (endpoints): in-model only if reachable by an unauthenticated or authenticated-but-untrusted HTTP client through the standard endpoints.
- scim-client: outside the adversary model — the remote server is trusted (§7) and the
Clientis the integrator's. Its obligations are integrator responsibilities (§9/§10), not adversarial-input handling.
- Runtime: a current, supported Java LTS — the exact floor is enforced by the build (17+ at time of writing). Memory-safety assumptions rest on running on a supported JVM.
- Concurrency:
SchemaRegistryandRepositoryRegistryare populated at startup by trusted integrator code and read concurrently thereafter; their backing maps are not synchronized for concurrent registration (onlyregisterRepositoryissynchronized). Assumption: registration completes before request handling begins. The shared JacksonObjectMapperis astatic finalsingleton, thread-safe once configured (documented: Jackson). - Memory model: standard JVM; no native code in the published libraries.
Verified by a source sweep across scim-spec, scim-core, scim-server, scim-client, and support/spring-boot main
sources (verified 2026-05-30). The published libraries:
- do not open listening sockets (the host container does);
- do not spawn child processes;
- do not read environment variables or system properties for behavior;
- do not read or write files;
- do not install signal/shutdown handlers;
- do emit logging via SLF4J, and do log resource objects and bulk dependency graphs at DEBUG level in
scim-server(BulkResourceImpl,BaseResourceTypeResourceImpl). With DEBUG enabled, non-secret SCIM attribute data can appear in logs — an operator responsibility (§10). Thepasswordattribute is not exposed this way (§8.1). - hold a process-wide
static finalJacksonObjectMapper; otherwise do not mutate global/process state.
Runtime configuration knobs (ServerConfiguration) (documented: source). These values are surfaced in the
/ServiceProviderConfig response, and the resource-limit knobs are enforced in the request path (§8.8):
| Knob | Default | Intended contract | Enforced today? |
|---|---|---|---|
bulkMaxOperations |
100 | enforced bound on bulk fan-out | Yes (§8.8) |
bulkMaxPayloadSize |
1024 | enforced bound | Yes (§8.8) |
filterMaxResults |
100 | enforced result bound | Yes (§8.8) |
supportsBulk / supportsFilter / supportsPatch / supportsSort / supportsETag / supportsChangePassword |
varies | capability advertisement | advisory only |
authenticationSchemas |
empty | capability advertisement | advisory only |
The capability supports* flags remain advertisements — they describe what the deployment offers, not access controls.
Build-time security tooling (documented: root pom.xml, .github/) — changes what the build guarantees,
relevant to §11a/§12: OWASP Dependency-Check (build fails on any CVE), SpotBugs + find-sec-bugs (max effort), PMD,
CodeQL, Dependabot, and a CycloneDX SBOM on release. (Exact tool versions live in the build, not here.) No build flag
changes a runtime security property in the published libraries.
| Endpoint / message | Parameter | Attacker-controllable? | Caller (integrator) must enforce |
|---|---|---|---|
GET /Users, /Groups |
filter (string) |
yes | authN before exposure |
GET /Users, /Groups |
startIndex, count |
yes | — (result size capped at filterMaxResults, §8.8) |
GET … |
attributes, excludedAttributes |
yes | — (mutually-exclusive check exists) |
POST/PUT /Users, /Groups, /Me |
JSON body | yes | body-size limits (container), schema trust |
PATCH /Users/{id}, /Me |
PatchRequest body incl. path |
yes | — (parsed; nesting depth capped, §8.7) |
POST /Bulk |
BulkRequest (operation array, failOnErrors) |
yes | — (operation count & payload size enforced, §8.8) |
| any mutating | If-Match header |
yes | — (parsed by EtagParser) |
GET /Me, PUT/PATCH/DELETE /Me |
caller principal | via container | authentication (endpoint requires a SecurityContext principal) |
GET /Schemas, /ResourceTypes |
filter |
yes | — (SCIMple returns 403 if present, per RFC) |
| Message | Parameter | Attacker-controllable? | Caller must enforce |
|---|---|---|---|
| outbound call | baseUrl |
no — caller-supplied | SSRF-safe URL |
| outbound call | the JAX-RS Client (TLS, creds, timeouts, redirects) |
no — caller-supplied | TLS verification, timeouts, credential handling |
| inbound response | remote SCIM peer's JSON body | no — the integrator trusts the server it calls | (out of model — §3, §7) |
Size / shape / rate: SCIMple relies on Jackson's built-in
StreamReadConstraints (max nesting depth, string/number length bounds) for JSON, and neither tightens nor loosens
them — these defaults satisfy the §8.7 "catastrophic" line for JSON depth/size. The ANTLR filter/PATCH grammar is
recursive; SCIMple caps nesting depth at FilterParsers.MAX_NESTING_DEPTH = 40 (§8.7). There is no input-length cap —
proportional cost is the integrator's/container's job (§9).
Assumed attacker:
- Untrusted SCIM client — can reach the server endpoints the integrator exposes and send arbitrary bodies, filter strings, PATCH paths, bulk operations, headers, and query params. May be unauthenticated (SCIMple enforces no authN itself) unless the integrator's layer blocks them first.
Capabilities they have: craft malformed/oversized/deeply-nested SCIM payloads; craft pathological filter/PATCH
expressions; submit large bulk batches. Capabilities they do not have: read/modify the embedding process's memory;
alter the
Repository, the registered schemas, or the Client configuration; observe local logs.
Attacker goals in scope: crash/hang the host via a small crafted input or super-linear cost (§8.7); read data
they shouldn't (e.g. password leakage); escape the parsed-object boundary or abuse deserialization; trigger
malformed-input failures. These goals are about subverting SCIMple's own machinery, and they hold regardless of how
privileged the authenticated caller is. They are not the consequences of operations the caller was authorized to
perform: SCIM is a high-privilege surface, and the blast radius of granted authority is governed by the integrator's
authorization (§3, §10), not by SCIMple.
Actors explicitly NOT in the model:
- Anyone with control of the embedding process or the integrator's
Repository/Client/schema registration — trusted code; they have already won. - The remote SCIM server that
scim-clientconnects to — the integrator selects it, holds credentials for it, and trusts it; a malicious/compromised remote server is out of scope (§3). - Local attackers reading DEBUG logs — a host operational concern (§9/§10).
This project is not a distributed/consensus system, so Byzantine-peer and honest-fraction concepts do not apply.
Each entry: property + conditions / violation symptom / severity / evidence. Severity is SECURITY-CRITICAL (warrants coordinated disclosure per
SECURITY.md) or CORRECTNESS-ONLY (ordinary bug).
- All
Returned.NEVERattributes (the only core one beingpassword) are stripped from responses, andpasswordis excluded from resourcetoString().
- Conditions: response flows through
AttributeUtil.setAttributesForDisplay;passwordisreturned = NEVER. - Violation symptom: a
password(or other NEVER attribute) appears in a SCIM response body or in logs viatoString(). Severity: SECURITY-CRITICAL (sensitive-data disclosure). Evidence: (documented) —ScimUser.passwordisreturned = NEVER;AttributeUtilstrips NEVER attributes;AttributeUtilTestassertsgetPassword()is null after display processing;ScimUser.toString()omitspassword. Regression-tested:AttributeUtilTestguards NEVER attributes out of responses (even when explicitly requested), andScimUserTestguards everyReturned.NEVERattribute out ofScimUser.toString()(schema-driven, so future NEVER fields are covered). Merged indevelop.
-
Untrusted filter / PATCH strings are parsed into structured objects before reaching the integrator's
Repository. Severity: CORRECTNESS-ONLY for SCIMple (any backend injection happens in integrator code; §9). Evidence: (documented) —Repository.find(Filter, …)/patch(id, List<PatchOperation>, …)take parsed types. -
No unsafe Jackson polymorphic deserialization. Violation symptom: gadget-chain deserialization (RCE). Severity: SECURITY-CRITICAL if violated. Evidence: (documented) — no
enableDefaultTyping/activateDefaultTyping; no@JsonTypeInfo/@JsonSubTypeson SCIM models (verified absent). -
Schema/extension registration loads no classes from untrusted input. Severity: SECURITY-CRITICAL if violated. Evidence: (documented) — registration is an explicit integrator API; no
Class.forNamefrom request data. -
No untrusted XML is parsed (no XXE surface in the published libraries). Severity: SECURITY-CRITICAL if violated. Evidence: (documented) — no
XMLInputFactory/SAXParser/DocumentBuilderFactory/Unmarshallerinscim-spec/scim-core(verified); JAXB API isprovided, annotation-only. See §11a. -
Filter / PATCH round-trip fidelity. Severity: CORRECTNESS-ONLY. Evidence: (documented) —
FilterBuilderTest,PatchOperationPathTest. Caveat: JSON string values are extracted by substring without unescaping (ExpressionBuildingListener.parseJsonType), so escaped sequences may not round-trip faithfully (correctness-only). -
Catastrophic-input resistance (resource bound). SCIMple commits to a categorical line: a small input that causes a crash (e.g.
StackOverflowErrorfrom a deeply nested filter/PATCH) or super-linear / exponential cost in input size is a bug SCIMple will fix; cost merely proportional to a large input is not (the integrator's job — §9).
- Violation symptom: small/cheap request →
StackOverflowError, hang, or exponential CPU/allocation. Severity: SECURITY-CRITICAL (DoS). - Provided:
FilterParsers.MAX_NESTING_DEPTH(= 40) caps nesting by counting entries into the recursivefilterExpression/attributeExpressiongrammar rules during parsing (aDepthCountingListeneraborts before the recursive-descent parser can overflow the stack), for both the filter parser and the PATCH-path parser. Over-limit input is rejected asFilterParseExceptionwith a fixed message that does not echo the input. JSON depth/size is bounded by Jackson defaults (§6). Evidence: (documented) —FilterParsers(MAX_NESTING_DEPTH = 40,DepthCountingListener), merged indevelop. There is no input-length cap; proportional cost is disclaimed in §9.
- Enforcement of advertised request limits. SCIMple enforces the configured
bulkMaxOperations,bulkMaxPayloadSize, andfilterMaxResultsin the request path.
- Violation symptom: a request exceeding a configured limit is processed anyway. Severity: SECURITY-CRITICAL
(DoS/fan-out) for the bulk bounds; CORRECTNESS-ONLY for
filterMaxResults. - Provided: a
/Bulkrequest exceedingbulkMaxOperationsis rejected with HTTP 413 (scimTypetooMany, per RFC 7644 §3.7.4) before any operation runs (BulkResourceImpl);bulkMaxPayloadSizeis enforced byBulkPayloadSizeFilter; query results are capped atfilterMaxResults(BaseResourceTypeResourceImpl). Evidence: (documented) — merged indevelop.
The most valuable section for an integrator. These are disclaimed by design unless a code citation notes otherwise:
- No authentication. SCIMple performs no authN of SCIM clients. Endpoints other than
/Meare reachable by anyone who can reach the route;/Memerely requires that aSecurityContextprincipal already exists (the container/integrator must supply it). Securing the endpoints is the integrator's job. (documented: noContainerRequestFilter/@RolesAllowed;SecurityContextused only inSelfResourceImpl.) - No authorization. No role/permission checks anywhere.
- No transport security.
scim-clientdoes not configure TLS; it uses the caller-supplied JAX-RSClient. Certificate/hostname verification, timeouts, redirect policy, and credentials are entirely the caller's responsibility. (documented: noSSLContext/TrustManager/HostnameVerifier/timeout code.) - No resistance to proportional resource cost. SCIMple bounds catastrophic input (§8.7) but makes no guarantee about resources consumed in proportion to a large but well-formed input (a huge body, a long flat filter, a large bulk batch within the intended limits). Bounding total input size/rate is the integrator's / container's job.
- No defense against a malicious
Repository, schema set, orClient. Trusted code (§7). - No password hashing or at-rest protection. SCIMple passes the cleartext
passwordtoRepository.create/update; hashing, storage, and never-logging are the integrator's responsibility. ( documented.) - No protection against operator-enabled verbose logging. With DEBUG enabled,
scim-serverlogs non-secret resource contents (§5/§10).passwordis excluded (§8.1), but other attributes are not.
returned = NEVERpassword redaction. It removespasswordfrom responses and fromtoString()(a real property, §8.1). It does not mean SCIMple protects the password elsewhere: the value is held in memory during request processing and passed in cleartext to theRepository. It is response/secret-in-log redaction, not secret management./ServiceProviderConfigsupports*capability flags.supportsBulk=false,supportsFilter=false, etc. look like enforcement switches; they are advertisements only — the endpoints behave identically regardless. (The numeric limit knobs are different —bulkMaxOperations/bulkMaxPayloadSize/filterMaxResultsare enforced; see §5a/§8.8.)
- Oversized / high-rate input (bodies, long filters, large bulk batches within limits) → proportional CPU/heap: bound size and rate upstream.
- Filter → backend injection (SQL/LDAP): SCIMple hands you a parsed
FilterExpression; parameterize any backend query you build from it. - SSRF via
scim-clientbaseUrl: validate the target before pointing the client at it. - Mass-assignment / over-posting on SCIM resources: validate which attributes a given caller may set.
- ReDoS on the
@Urnvalidator regex against malformed URNs (low-likelihood; see §11a; note §8.7 would classify a genuinely super-linear case as a bug).
For SCIMple, "downstream" = the integrator/operator. To make §5–§7 hold, they MUST:
- Authenticate and authorize every SCIM request before it reaches SCIMple endpoints. SCIM is a high-privilege surface (it manages users, groups, and passwords), so apply least privilege: scope what each SCIM client may do rather than granting blanket create/modify/delete. A compromised or over-privileged client is "game over" at the identity layer no matter how robust SCIMple's parsing is — this authorization boundary is the primary control.
- Terminate and verify TLS for inbound serving and the outbound
scim-clientClient(certificate + hostname verification, sane timeouts). - Bound untrusted input at the edge: request body size, bulk batch size, and request rate. (SCIMple bounds catastrophic parser cases per §8.7 but not proportional cost.)
- Implement the
Repositorysecurely: hash passwords, never log secrets, parameterize any backend query built from aFilterExpression, and enforce per-caller authorization on every operation. - Do not enable DEBUG logging in production, or scrub it —
scim-serverlogs non-secret resource contents at DEBUG (§5). (passwordis excluded.) - If you point
scim-clientat a server you do not control or fully trust, treat its responses as untrusted input — the default model assumes a trusted, integrator-chosen peer (§7).
- Exposing SCIMple endpoints directly to the internet with no auth in front. The endpoints ship without authN/authZ; unguarded exposure yields unauthenticated CRUD over users/groups. Instead: gate every route behind the host's auth layer.
- Assuming
/ServiceProviderConfigsupports*flags enforce behavior. Instead: enforce capability decisions in the integrator/container; the flags only advertise. - Relying on SCIMple to bound all input cost. Forwarding unbounded bodies/batches. Instead: cap size and rate at the edge (SCIMple covers catastrophic parser cases only, §8.7).
- Building backend queries from
FilterExpressionvia string concatenation. Injection. Instead: parameterize / useBaseFilterExpressionMapperpatterns. - Treating response
passwordredaction as secret management. Instead: hash and protect the secret in theRepository. - Logging at DEBUG in production. Leaks non-secret resource contents. Instead: keep production at INFO+ or scrub.
Feed this back to tooling as a suppression list.
Reasoned non-findings (not in a suppression file, discharged by a §8 property):
jackson-databind"unsafe deserialization." Safe: no default typing and no@JsonTypeInfo/@JsonSubTypesin the published sources (verified); SCIM payloads bind to a fixed model (§8.3).- "XXE in JAXB." Safe: no untrusted XML is parsed — no
XMLInputFactory/DocumentBuilderFactory/SAXParser/Unmarshallerinscim-spec/scim-core(verified); JAXB API is annotation-only,providedscope (§8.5).
Suppressed in src/spotbugs/excludes.xml:
EI_EXPOSE_REP/EI_EXPOSE_REP2(object exposes its internal representation) — suppressed for thespec.filter.*andspec.phonenumber.*model packages. Mutable-field exposure on value/model objects, not an attacker-input issue.REDOSonUrnValidator— the URN-validation regex is suppressed as a false positive (the maintainers judged it non-backtracking). Note: a URN can arrive in request data, so per §8.7 a genuinely super-linear case would be aVALIDbug — re-evaluate if that regex changes.UNENCRYPTED_SERVER_SOCKET— only inEmbeddedServerExtension(thescim-compliance-testsintegration-test harness); out of scope per §3.RCN_REDUNDANT_NULLCHECK_…(suppressed globally) and thePhoneNumberbuilder findings (UWF_FIELD_NOT_INITIALIZED…,NP_NULL_ON_SOME_PATH…),ObjectMapperFactoryMS_EXPOSE_REP, andBaseScimClientCT_CONSTRUCTOR_THROW— code-quality false positives (largely Lombok-generated code), not security-relevant.
Suppressed in src/owasp/suppression.xml (dependency-scan noise):
- Wrong CPE/GAV matches: SCIMple JARs mis-identified as Apache HTTP Server;
junit-platform-engineas the "fan_platform" Python project;commons-codec/commons-logging/jcl-over-slf4jmis-linked tocommons_net. - Weld
probe.js(old jQuery/Bootstrap) CVEs.weld-se-corebundlesprobe.js; it is test-scoped in the published libraries (scim-client,scim-server) and a runtime dependency only of the Jersey demo examples. The JS asset is never in a published artifact's runtime surface and SCIMple never serves it. - SnakeYAML
CVE-2022-1471— transitive dependency; the unsafeConstructorpath that triggers it is not used.
Revise this document when any of the following occurs:
- A new public endpoint, accepted input format, or protocol message is added.
- SCIMple begins parsing untrusted XML, or enables Jackson default typing (would void §8.3/§8.5), or overrides Jackson's
StreamReadConstraints. - A core attribute beyond
passwordis markedReturned.NEVER, orScimUser.toString()is regenerated (e.g. switched to Lombok@Data) — re-verify §8.1. scim-clientgains its own transport/credential handling, or SCIMple adds authN/authZ (would move items from §9 to §8).- A shipped-but-unsupported component (an example, the LDAP reference project) is promoted into a published artifact.
- Evidence the model is incomplete: a vulnerability report that cannot be cleanly routed to a §13 disposition is
itself a trigger (
MODEL-GAP) — add the missing property to §8 or §9 rather than making an ad-hoc call.
Ownership/cadence: the Apache Directory PMC owns this document; it is re-reviewed at each release and whenever a trigger above fires. Each release's git tag binds that release's copy (§1).
| Disposition | Meaning | Licensed by |
|---|---|---|
VALID |
Violates a property the project claims, via an in-scope adversary and input. | §8, §6, §7 |
VALID-HARDENING |
No §8 property is violated, but the API makes a §11 misuse easy enough that the project elects to harden it. Reported privately; fixed at maintainer discretion; typically no CVE. | §11 |
OUT-OF-MODEL: trusted-input |
Requires attacker control of a parameter the model marks trusted (e.g. baseUrl, the Repository, registered schemas). |
§6 |
OUT-OF-MODEL: adversary-not-in-scope |
Requires a capability the model excludes (e.g. control of the embedding process). | §7 |
OUT-OF-MODEL: unsupported-component |
Lands in scim-server-examples/**, reference-projects/**, or test/CI tooling. |
§3 |
OUT-OF-MODEL: non-default-build |
Only manifests under a discouraged or non-default §5a configuration. | §5a |
BY-DESIGN: property-disclaimed |
Concerns a property the project explicitly does not provide (authN/authZ, transport, proportional resource cost, password hashing). | §9 |
KNOWN-NON-FINDING |
Matches a documented recurring false positive. | §11a |
MODEL-GAP |
Cannot be cleanly routed to any of the above → revise the model. | triggers §12 |
A sidecar threat-model.yaml accompanies this prose for automated/AI triage, carrying only the
triage-relevant facts: entry points → per-parameter trust (§6), component families → in/out of scope (§2/§3), config
knobs → security-relevant?/default?/enforced? (§5a), claimed properties → severity + violation symptom (§8), disclaimed
properties + false friends (§9), known non-findings (§11a), and the disposition labels (§13).
The prose remains canonical; the YAML is a derived index. It pins no version — the release git tag binds both files (§1). Regenerate it whenever this prose changes.