In the following proposal I suggest a secure mechanism for event notifications.
The purpose of this design is to maximize security. As with all my recent work,
e.g. the aREST design for application-level notification support, it is an
experiment to explore a particular aspect of the problem space.
Many solutions for implementing HTTP notifications use callbacks to a sink-side
HTTP server. However running a full featured HTTP server creates very serious
security problems. From a security perspective an ideal solution would be only
a little less secure than running an HTTP client, and running a full server
makes that impossible.
The sink must operate a protocol designed for extreme paranoia. I will call
this protocol "Paranoid Sink Protocol", or PSP. The goal of PSP is to make HTTP
event notifications secure. The name "PSP" is a placeholder -- it may or may
not be HTTP. PSP exists exclusively to notify HTTP clients that they should
initiate an HTTP request. All risky activities are performed via requests, thus
preserving the existing security levels of web clients.
DESIGN
=======
Here is a sample of a PSP transaction:
1) A client uses HTTP 1.0 or later to request notifications on a resource. The
client provides a PSP URI. The client and server construct a secure ticket to
identify valid PSP notifications. The ticket might, for example, be a public
key or a secret token. The server provides a URI for picking up events once
notification has been received.
2) Time passes.
3) The source node emits a PSP notification. The notification contains only
enough information to validate the ticket. It does not contain the callback
address. It is a fixed length to prevent buffer overflow attacks.
4) The sink validates the ticket and disconnects without a response of any kind.
5) The sink requests the event from the event pickup URI.
To prevent port scanning, PSP does not return either a TCP ACK or an HTTP
response. However there does exist an ACK in the form of the sink poll in #5
above. A source MUST assume that a #3 notification not followed by a #5 poll
has not been received.
To prevent buffer overflows and to make TCP unnecessary, PSP uses fixed length
messages. 512 bytes should be enough.
To protect the sink from malicious parties, notifications MUST be idempotent.
The sink need not store any information about the message after transmission.
All notifications and polls related to a specific ticket are identical. A
single poll picks up all stored messages.
IMPLEMENTATION
==============
For an implementation of PSP, HTTP 0.9 fits perfectly. It can legally ride over
UDP or IP, does not require any response at all, and only supports idempotent
operations. Its brutally trivial nature makes implementations orders of
magnitude easier to secure than HTTP 1.1 implementations.
The security of PSP is dependent on security of the (#1) event subscription and
ticket negotiation. Adequate security of #1 is a big what-if. Design of the
ticket negotiation is a challenge to be taken seriously.
To prevent packet sniffers from spoofing notifications, the ticket should be
renegotiated at each (#5) request. Since the request will not be observable
before the first notification is sent, and subsequent notifications (spoofs or
not) have no effect, sucessful spoofing will have no worse an effect than
sending random packets.
It is apparent that, due to the requirement that notifications must be followed
up with a request, PSP is not designed for performance. The only problem it
addresses is security.
See http://www.w3.org/Protocols/HTTP/AsImplemented.html for the HTTP 0.9
specification.
- Lucas