Why does a valid WS-Security signature not stop a recorded SOAP message from being replayed, and what does a signed wsu:Timestamp add?
answer
- origin and integrity, not freshness
- Created and Expires, in UTC
- whose clock decides expiry
- remember what you have seen
- unsigned, it can be edited
basics
~20 sA signature proves who produced the bytes and that they are unchanged, so an exact copy verifies again. A signed wsu:Timestamp adds Created and Expires times the receiver can check, bounding how long a copy works and how much history it must remember.
solid answer
~40 sWS-Security's own security considerations say digital signatures alone do not provide message authentication: a recorded signed message can be resent and still verifies. `<wsu:Timestamp>`, a child of `wsse:Security` allowed at most once per header, carries optional `wsu:Created` and `wsu:Expires` times in UTC. Recipients are strongly RECOMMENDED to discard messages past `Expires`, and may report it with the `MessageExpired` fault code. A copy sent inside the window is still fresh, so the receiver also caches what it has seen for a period (five minutes is the guideline minimum) and rejects repeats and older messages. The timestamp must itself be **signed** with the Body, or an attacker simply rewrites it. Expiry is judged against the **requestor's** clock; WS-Security does not synchronise time, so the receiver decides how much skew to tolerate.
go deeper
Recall that a signature proves origin and integrity but not freshness, and that wsu:Timestamp holds Created and Expires in UTC.
Explain the receiver's sequence: verify a signature that covers the timestamp, reject expired and stale messages, then check a cache of recent ones.
Show how you would set the freshness window and skew tolerance for a real partner, and what cache you need when the service runs on several nodes.
Weigh timestamp windows against sequence numbers or message correlation, and decide which replay guarantee a business operation actually needs.
## What a signature proves, and what it does not An XML signature in a `wsse:Security` header lets a receiver check two things: the signed elements have not changed, and they were signed by whoever holds the key. Neither says *when* the message was sent or whether this is the first time it has arrived. WS-Security's security considerations put it directly: "Digital signatures alone do not provide message authentication. One can record a signed message and resend it (a replay attack)." A replayed payment instruction or claim submission verifies perfectly. The specification names four typical approaches to detecting replays: **timestamps**, **sequence numbers**, **expirations** and **message correlation**. The mechanism it defines itself is the timestamp. ## The wsu:Timestamp element | Rule | What the specification says | |---|---| | Placement | a child of `wsse:Security`, at most once per header, so once per actor or role | | `wsu:Created` | optional, at most once: the instant the message was serialised for sending | | `wsu:Expires` | optional, at most once: when the sender says the security semantics stop being valid | | Time format | `xsd:dateTime` RECOMMENDED; all times MUST be in UTC; no leap seconds | | Order | the children's order is fixed and MUST be preserved by intermediaries | | Unknown children or attributes | SHOULD cause a fault | The fault code for an expired message appears in the specification's error table as `wsse:MessageExpired`; a service MAY return it, but is not obliged to. ## How a receiver uses it 1. **Verify the signature first**, and confirm that it covers the Timestamp. The specification strongly RECOMMENDS signing timestamps and IDs, because an unsigned timestamp can be rewritten to any value. 2. **Reject expired messages**: anything past `Expires` should be discarded. 3. **Reject stale messages**: messages older than a chosen period are rejected in interactive scenarios; five minutes is the specification's guideline minimum. 4. **Remember what arrived within that period.** Inside the window, a copy is as fresh as the original. The specification suggests caching timestamps, for example the latest one per sending service; keying the cache on the signature value or a message identifier is a common implementation choice. The window is what makes step 4 affordable: a cache only has to cover messages young enough to pass step 3. ## Whose clock WS-Security provides no way to synchronise time. Expiry is relative to the **requestor's** clock, so the recipient MUST assess how far it trusts that clock, and may estimate skew from `Created` and the delays of intermediaries. In practice receivers allow a tolerance in both directions and rely on synchronised clocks outside the protocol. Creation time SHOULD NOT differ substantially from transmission time. ## Timestamp versus the UsernameToken's own fields - The UsernameToken profile carries its own `wsse:Nonce` and `wsu:Created` inside the token and mixes them into a password digest; that protects the **token** against replay. - `wsu:Timestamp` describes the freshness of the **message's** security semantics as a whole, and does its job only when signed together with the Body. - Neither stops a message being replayed to a *different* receiver that keeps a separate cache. ## Running the check on more than one node A service that runs as several instances behind a load balancer meets the same problem the UsernameToken profile describes for separate clusters: a copy sent to an instance that never saw the original passes that instance's local cache. The specification does not say how to share the record, so this is an implementation decision: - a cache shared by every instance that accepts the same messages, sized for the freshness window; - or routing that sends a given sender's traffic to one instance, which only moves the problem to failover; - or an application-level guard, such as rejecting a business identifier already processed, which the specification counts under message correlation. Whichever is chosen, the window and the cache lifetime must match: a cache that forgets entries sooner than the window reopens a gap in which copies are accepted. ## Common mistakes - Treating a valid signature as proof the message is new. - Accepting an unsigned timestamp as evidence of freshness. - Writing local times without a UTC designator. - Setting a freshness window but keeping no record of what arrived inside it.
- Why must the wsu:Timestamp be covered by the message signature?An unsigned timestamp is just text an attacker can rewrite: a replayed message gets a fresh `Created` and a later `Expires`, and every freshness check passes. WS-Security therefore strongly RECOMMENDS signing timestamps and IDs, so the receiver knows the times are the ones the sender wrote, bound to the same Body.
- A receiver's clock runs three minutes behind the sender's; what goes wrong, and how do you handle it?Fresh messages appear to come from the future and the window effectively shrinks or shifts, so valid calls may be rejected, or stale ones accepted. WS-Security does not synchronise clocks; it says the receiver must judge the requestor's clock. Receivers allow a skew tolerance in both directions and keep clocks synchronised by means outside the protocol.
A signed cheque: the signature proves who wrote it, not that this is the first time it is presented. The date limits how long it can be cashed, and only the bank's record of cheques already paid catches a second presentation inside that period.
saying these in an interview costs you the question
- A signed SOAP message cannot be replayed because the signature would fail.
- WS-Security synchronises the sender's and receiver's clocks.
- An unsigned wsu:Timestamp is enough to detect replayed messages.
- wsu:Timestamp times may be written in the sender's local time zone.
- One Security header may carry several wsu:Timestamp elements.
- Expires is mandatory in every wsu:Timestamp.