Computational Puzzles for SPAM
Reduction in SIPCisco Systems170 West Tasman DriveMS: SJC-21/2San JoseCA95134USA+1 408 421 9990fluffy@cisco.comOne of the techniques used in SPAM prevention and various solutions
for denial of service attacks is to force the SIP client requesting a
service to perform a calculation that limits the rate and increases the
cost of the request. This draft defines a way to allow a UAS to ask the
UAC to compute a computationally expensive hash based function and
present the result to the UAS. Although the computation is expensive for
the UAC to compute, it is cheap for the UAS to verify. The solution also
allows for proxies to compute and check the puzzle on behalf of the UAC
or UAS.This draft currently outlines enough information to evaluate and
consider this approach or even run experiments. It would need
finalization around the forking topics discussed in the open issues
before it would be implementable in production system.The SPAM prevention problem is complex and will require many
techniques working in combination to balance reducing SPAM to acceptable
levels while still fostering efficient communication. The overall
problem and various approaches are in . Clearly white lists are a
critical part of dealing with SPAM. Any system would first check whether
an incoming request for communications was from someone on the white
list. The Identity mechanisms are critical
for understanding who the caller is and to check whether the caller is
on the white list. As well, there still needs to be a way for callers
not on the white list to communicate with the user. It is here that this
specification becomes relevant.The problem is how to permit contacts from people with no previous
relationship to us without receiving undesirable contacts. This draft
uses the idea that it may be possible to make undesirable contacts more
expensive than desirable ones.Different undesirables are willing to spend different amounts of time
and money on contacting their markets. Founders of acquired startups are
often contacted by random financial companies offering to help manage
the new riches. These companies will send people from New York to San
Jose and spend hours talking to this very narrow target market. Clothing
retailers will mail glossy catalogues worth $1 apiece to houses within
the right demographic zip codes. Emails advertising Viagra are sent to
random email addresses. As the costs go down, the volume of unsolicited
contact goes up.Often people whose contact is desirable are willing to spend much
less than some of the undesirables. The student in Fiji who wants to ask
about this draft will send an email but probably will not fly here to
talk to me. I would like to receive that email.Increasing the cost of contact will reduce both desirable and
undesirable contact. My assumption is that the cost should be set very
low, so that even a person with a pathetic CPU could still make contact
in, say, 10 seconds. Key to this draft is that the receiver can set this
cost. This low cost will not stop the financial advisers or the
telemarketers, but it might stop the Viagra ads. It would also probably
stop a single user from ringing every phone of some residential service
provider in a five-second window, before any operator or system can
react. Deciding what cost to set constitutes a classic type I/type II
error problem, and the receiver gets to choose how to balance these two
errors.As is clearly stated in ,
whitelists are the best thing. After that, this is one of the multiple
other options that need consideration.In general there are two arguments about why the computation puzzles
in this specification will not work. The first is that the bad guys have
the most powerful CPUs. This issues was addressed above. The other
argument is that bad guys have infinite CPU time through using armies of
zombie PCs. The problem with this argument is that the goal is not to
block particular bad guys but to reduce the overall number of
undesirable messages. This second argument is, however, more worrisome
than the first.Assume that some percentage of the world's machines each year get
owned and used as zombies. Let's say that a given machine has 1% of
having this happen to it in a year, that it sends zombie traffic for 24
hours before getting shut down, and that the mechanism described here
limits it to ten messages per second: each machine on the internet would
receive an average of about one undesirable message per hour. If you
assume there are more users than machines, this looks appealing. If
message sending technology detects users that are sending lots of
messages and shuts them down in less than 24 hours, it gets better. It
gets better still if you hope for improvements in operating systems or
for users to choose them more carefully. The next assumption is hard to
model statistically but it is true: the people with the best financial
incentives to send undesirable messages do not want to be subject to the
legal and reputation problems of using zombies to get their message
across.The zombie problem basically comes down to this. If there are a small
percentage of machines in the world that are zombies, they do not render
this computation puzzle approach useless. If 10% of the machines in the
world are zombies, this approach will be useless. This specification
does not attempt to deal with how to make the world such that a small
percentage of computers are zombies - the is the problem for other work
and that work needs to happen for SPAM to be reduced to reasonable
level. This specification does assume that the zombie problem is solved
to the level where a small percentage of the worlds computers are
zombies.Clearly there is a need to be able to initiate SIP communications
from very low power, low cost, devices. They will have relatively slow
CPUs and their users will be very impatient and only willing to wait a
short time to compute the puzzle. On the other hand there will be
attackers with very fast computers and possibly many of them. The
relative ratio of these speeds and size of the attacker population will
determine how effective this approach is.So in summary, white listing is the first and best defense. But for
dealing with messages from people with whom we have not previous direct
or indirect relationship, another approach is necessary. Puzzles cannot
stop all bad messages - that is not the goal - but it can raise the cost
of messages and thus decrease the number of times it makes economic
sense to send undesirable ones. This approach does assume that bad guys
will have more CPU power than good guys and that zombies will still send
lots of messages. This approach will simply reduce the number of
undesirable messages by some amount that cannot be measured.No one knows if this approach would reduce SPAM noticeably. Right now
the only thing that limits the rate at which I can call every SIP phone
in the world is proxies getting overloaded. And of course, most SIP
phones are not connected to the public internet. The SPAM problem is one
reason why many SIP phones are not connected to the public internet.
There are some other approaches outlined in . They have different pros and
cons, and it is probably necessary to use most of them to ensure SPAM
stays at an acceptable level.This specification extends RFC 3261 and
defines a mechanism for a proxy or UAS to request that a UAC compute the
solution to a puzzle. The puzzle is based on finding a value called the
pre-image that, when hashed with SHA1,
results in a specific value referred to as the image. The goal is for
the UAC to find a pre-image that will SHA1 hash to the correct image.
The UAS provides a partial pre-image with some of the low order bits set
to zero, together with the number of bits in the pre-image that have
been set to zero.The UAS provides the puzzle information using a 419 response, and the
UAC resubmits the request along with the solution to the puzzle. The
high level flow of information is shown below.|
| |
| 419 with Puzzle |
|<-------------------------|
| |
| Request with Solution |
|------------------------->|
| |
]]>This specification defines the 419 response code along with a new
header, called Puzzle, to carry the puzzle and solution.The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in
RFC 2119 .The normative definition of a puzzle is as follows. A puzzle is four
values: an integer number referred to as work, a pre-image string, an
image string, and a integer number referred to as value. There MUST
exist a value X such that all but the "work" number of low order bits of
X match the pre-image string, and the SHA1 hash of the string formed by
the concatenation of "z9hG4bK" and X results in a value Y, where the
"value" number of low order bits of Y are the same as those bits in the
image string. The SHA1 hash is computed as described in RFC 3174. The value X is the solution to the
puzzle. The 'work' number of low order bits of the pre-image MUST be
zero.This can all be described more mathematically. The notation low(v,x)
returns the first v number of low order bits of the value x, and
zero(v,x) returns x with the lowest v number of bits set to zero. The |
operator signifies string concatenation. The solution to the puzzle can
be considered finding an X such that both the following are true:The pre-image forms a constraint on X. The value of X is the same
pre-image, other than the low 'work' bits that are set to zero in the
pre-image. The 'value' is the number of bits that match in the solution
and is typically set to 160, which is the full size of the SHA1 hash
result.The following is a non-normative way for a UAS or proxy to construct
a puzzle. The following strings are concatenated:a secret that only this device knows. This would typically be a
crypto random string of bits;the current timethe URI of the request, the Call-ID, the From tags, and the
branch tag for a proxy or the To tag for a UAS.The string is hashed with SHA1 to form the pre-image. The pre-image
is appended to the string "z9hG4bK", and the SHA1 hash of this is
computed to get the value of the image. A value 'work' indicates how
many bits of the pre-image are to be removed. The value 'work' could be
a configurable parameter, or it could be dynamically discovered by the
software based on how long a hash should take and the speed of the
computer it was running on. In the latter case, the resulting software
would automatically choose larger values of 'work' as computers get
faster. The low order 'work' bits of the pre-image are set to zero. The
puzzle consists of the chosen value of 'work', the pre-image (with the
low order bits set to zero), the image, and the 'value'. The 'value'
would typically be set to 160 as this is the size of the SHA1 hash.
Since the time was roundedNote: Some implementors have pointed out that this approach requires
the UAS to do a SHA1 to compute the puzzle and that this creates extra
load on the UAS. On a machine with a proxy that could process about
thousand sip transactions per second, the approximate rate of puzzle
creation was over one million puzzles per seconds. The work to create a
puzzle is trivial compared to the work to receive a sip messages and
send the response. The advantage of a puzzle in this form seemed
apparent at some time in the past but I can not remember why. Big TODO
item to recall why this form was used. This form does allow
progressively better solutions to be found with a higher "value" without
changing the image string.When a UAS wishes to challenge a request, it MAY create a puzzle,
encode this puzzle in a Puzzle header field value, and return the
puzzle in a 419 response.When a UAC receives a 419 response, it needs to look at the 'work'
and 'value' requested and decide whether or not to try to solve this
puzzle. This decision can be made based on the programmed policy and
possibly human input. The UAC should not tackle a puzzle that will
take longer than the age of the universe to solve. If the UAC chooses
to try to solve the puzzle then it proceeds along the following
steps:Check that the 'work' bottom bits of the pre-image are all
zero. If they are not, this is an invalid puzzle and the 419
response MUST be considered an error response.Set Y to low( value, image ).Create a loop where X ranges from the value of the pre-image to
the value of the pre-image plus 2 raised to power of the
'work'.For each interaction through the loop, check if low( value,
sha1( "z9hG4bK" | X )) equals Y. If it does, a solution X has been
found and the loop can terminate.If the loop terminates without a solution being found, the puzzle
was bad and the 419 response MUST be considered as an error
response.Once the solution to the puzzle, X, is found, a new request is
formed by copying the old request and adding an additional puzzle
header field value. The new puzzle header field value MUST have the
'work' set to 0, the pre-image set to the value X, the image set to
the value of the image in the original puzzle, and the value parameter
set to the same as the value parameter in the original puzzle. Note
that if a request was challenged by one proxy and a new request was
generated with a solution, and then this request was challenged by a
second proxy, a third request would be generated that had two Puzzle
header field values. If a UAC, through some out of band mechanism,
knows that it will be challenged and what the puzzle will be, it MAY
include the appropriate puzzle header field value in the initial
request.SIP allows proxies to act as UASs when generating 4xx responses.
This same mechanism can be used to allow a proxy to generate the
challenge on behalf of a UAS in its domain.Proxies may also act on behalf of the UAC and compute the solution
to a puzzle on behalf of the UAC in either a request or a response
that passes through the proxy. Typically a proxy would only do this
for a UAC that had authenticated to the proxy and for which the proxy
had a service relationship.In this example, we present a communication establishment between two
users, Alice (sip:alice@example.com) and Bob (sip:bob@example.net).
First, Alice sends an INVITE to Bob. Bob, who wants to make sure that
Alice is not a spammer, replies to Alice with a message "419 - Puzzle
Required'', indicating that he wants Alice to pass a challenge before
establishing a communication. Bob's reply contains a Puzzle that Bob
wants Alice to solve. To get the "preImage'' value, Bob generates a
random string that he hashes with SHA1. If we define "SHA1'' as the
method that hashes a string: To get the "image'', Bob appends the string "z9hG4bK" to his
"preImage'', and he hashes this new string with SHA1 again. We can say:
where the "|" operator signifies string concatenation.Bob chooses to fix the value of "value'' to 160, as it is the size
(in bits) of the "preImage'' and the "image'' that he's going to send to
Alice. As seen before, the value of "work'' determines the difficulty of
the problem, and has to be set up depending on the power of Alice's UA.
To simplify the problem, let's suppose that Bob chooses to fix "work''
to 15. Before putting these values into the "Puzzle header'' field, Bob
saves the value of his "preImage", and applies the method "zero(value,
preImage)" to set the "value" bottom bits of "preImage'' to 0.If we assume that Bob has picked the random string
"itjjyfdubtpneggrdsaavouy", he has the following values: Then Bob constructs the Puzzle header field, that has this
form: At this point Bob answers to Alice's INVITE, with a message
"419 Puzzle required" containing the "Puzzle header" field that he has
just built. When Alice receives this message, she looks at the value of
"work" and "value", and in our case she decides to try to solve this
puzzle. She decodes the "preImage'' and the "image'' with a
base64-decoder. Then she checks that the "work" bottom bits of preImage
are set to 0. If it is not the case, she would have to consider the 419
message as an error message. Alice creates a variable Y, set to
low(value, image). She creates another variable, X, that will contain
the solution, and that is initialized to the preImage that she has read
in the "Puzzle header" field.The binary value of X, before starting to search for a solution,
is:01010110 00000101 01000110 01100010 00101100 01011011 01000110
00001101 00100110 01110101 00101100 00010011 01100011 01110110 00001000
01111100 00100000 01101110 00000000 00000000In fact it's the same value as the "preImage'' that Bob has put in
the "Puzzle header" field, because Alice has initialized X to this
value. This "X" is the start-point of solving the puzzle.Then she starts looping...While low( value, SHA1("z9hG4bK" | X )) doesn't equal Y, she must
"increment" X, ie binary add 1 to the bit-representation of X. In other
words, if during a given iteration the binary value of X is:01010110 00000101 01000110 01100010 00101100 01011011 01000110
00001101 00100110 01110101 00101100 00010011 01100011 01110110 00001000
01111100 00100000 01101110 00010010 10010111then Alice has to add 1 to this value, and the new binary value of X
must be:01010110 00000101 01000110 01100010 00101100 01011011 01000110
00001101 00100110 01110101 00101100 00010011 01100011 01110110 00001000
01111100 00100000 01101110 00010010 10011000The maximum number of iterations is "2^work", because Alice has
received a "preImage'' with the "work" bottom bits set to 0, and that
the biggest solution would can be the "preImage'' with the "work" bottom
bits set to 1. This configuration is accessible via "2^work"
iterations.If Alice has finished looping without finding a solution, she must
consider that the puzzle was invalid, and then consider the "419 Puzzle
Required" as an error message.If Alice finds an X such as low( value, SHA1("z9hG4bK" | X )) equals
Y, she has the solution! She can break out of the loop and build a
response for Bob.As a response, Alice will send a copy of her initial request, but she
will insert the same "puzzle header field" as the one she has received
in the "419 Puzzle Required", except the "work" field that she sets to
0, and the "preImage" field where she puts the solution of the problem.
She won't forget to base64-encode her solution, X, before putting it in
the "Puzzle header" field.The "Puzzle header" field of Alice's answer has the form: When Bob receives this message, he can compare the
"preImage'' value that he has used to build the Puzzle with the
"preImage'' value that he can read in the "Puzzle header" field of
Alice's answer.If these two values are the same, he can consider that Alice has
spent time to solve the puzzle, and that she passed the challenge. So he
can accept her initial INVITE request!In conclusion, we saw different messages going between Alice and Bob.
Here is a summary of these messages, and the content of the "Puzzle
header" field" for messages that use this header: |
| |
| 419 with Puzzle |Puzzle: work=15;
| |pre="VgVGYixbRg0mdSwTY3YIfCBuAAA=";
|<-------------------------|image="NhhMQ2l7SE0VBmZFKksUC19ia04=";
| |value=160
| |
| INVITE with Solution |Puzzle: work=0;
| |pre="VgVGYixbRg0mdSwTY3YIfCBuYmg=";
|------------------------->|image="NhhMQ2l7SE0VBmZFKksUC19ia04=";
| |value=160
| |
| 100 TRYING |
|<-------------------------|
| |
| 180 RINGING |
|<-------------------------|
| |
| 200 OK |
|<-------------------------|
| |
| ACK |
|------------------------->|
]]>The Puzzle header field carries the puzzle and solution information.
It has a parameter called 'work' that has the number of bits of the
pre-image that have been set to zero for this puzzle. It has a parameter
called 'pre' that carries the pre-image string base64 encoded, and a
parameter called 'image' that carries the image string base64 encoded.
In addition there is a parameter called 'value' that indicates how many
bits of the resulting hash will match the 'image' string. The base64
encoding is done as described in RFC
3548.When the header field value is carrying a solution to a puzzle, the
work parameter will be set to zero.Example:The ABNF for the header is:This document updates the dreaded Table 2 of RFC 3261 to be:The current mechanism has poor interaction with the HERD forking
problem. If several endpoints sent a 419, the proxy would need to
aggregate the results and add something like the realm to the challenges
to keep them sorted out. Need to add this in next revision. In many
cases the solution would work out better if the proxy that was doing the
forking applied the policy and did the 419 before forking. This approach
has the usual HERD problem that if some UAs do a 419, and some UAs
don't, the request will only reach the UAs that don't do the 419.What is the transition model here. Not everything is going implement
this right away: how to differentiate non-implementers from purposeful
non-implementors? Is it realistic to just say no to non-implementors?
Especially when you consider that as a PANT replacement there is a
general expectation of call success rather than call failure (unlike,
say, IN).Need to add a parameter to the puzzle that specifies which hash
algorithm to use.Update what happens when a UAS receives a puzzle with an incorrect
solution.Still TBD.The concatenation with "z9hG4bK" is done so that this mechanism
cannot be used as a distributed computation to reverse arbitrary hash
values, as that would present a security risk for other hash based
security schemes.TODO - Advice on selecting the size of 'work'.There may be ways of using this to effectively perform DOS attacks on
system by asking them to solve many puzzles. Need to consider these
attacks and make sure that puzzles are only needed to be solved by the
device the initiated the requested action.TODO - discuss rational for design of the puzzleSome applications like "reverse 911" (community emergency alert
systems that notify all the UAs in a given group or geographic region)
would be severely hampered by being challenged with puzzles. These
systems will require some other authorization system and SHOULD NOT use
this approach.This specification registers a new header and a new response code.
IANA is requested to make the following updates in the registry at:
http:///www.iana.org/assignments/sip-parametersAdd the following entry to the header sub-registry.Add the following entry to the response code sub-registry under the
"Request Failure 4xx" heading.The test vectors in Appendix A and the example text were provided by
Geoffrey Dawirs. This approach was motivated by . Michael Thomas has pointed out some
significant problems with this idea and perhaps the whole approach. I
have tried to paraphrase some of his concerns into the discussion in
this document. Henning Schulzrinne pointed out the important reverse 911
consideration.The test vectors were run with 17 different levels of work ranging
from 1 to 17. For each level of work three puzzles are created and
solved and are labeled TEST 1,2, or 3.The Base16, Base32, and Base64 Data EncodingsKey words for use in RFCs to Indicate
Requirement LevelsHarvard University1350 Mass. Ave.CambridgeMA 02138- +1 617 495 3864sob@harvard.edu
General
keywordSIP: Session Initiation ProtocolUS Secure Hash Algorithm 1 (SHA1)http://www.hashcash.org/The Session Initiation Protocol (SIP) and Spam