1352
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are
duplicated on the server side. Attackers can bypass the client-side checks by modifying values
after the checks have been performed, or by changing the client to remove the client-side checks
entirely. Then, these modified values would be submitted to the server. Even though client-side
checks provide minimal benefits with respect to server-side security, they are still useful. First,
they can support intrusion detection. If the server receives input that should have been rejected
by the client, then it may be an indication of an attack. Second, client-side error-checking can
provide helpful feedback to the user about the expectations for valid input. Third, there may be
a reduction in server-side processing time for accidental input errors, although this is typically a
small savings.
Phase: Architecture and Design
If some degree of trust is required between the two entities, then use integrity checking and
strong authentication to ensure that the inputs are coming from a trusted source. Design the
product so that this trust is managed in a centralized fashion, especially if there are complex
or numerous communication channels, in order to reduce the risks that the implementer will
mistakenly omit a check in a single code path.
Phase: Testing
Use dynamic tools and techniques that interact with the software using large test suites with
many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The
software's operation may slow down, but it should not become unstable, crash, or generate
incorrect results.
Phase: Testing
Use tools and techniques that require manual (human) analysis, such as penetration testing,
threat modeling, and interactive tools that allow the tester to record and modify an active session.
These may be more effective than strictly automated techniques. This is especially the case with
weaknesses that are related to design and business rules.
Demonstrative Examples
Example 1:
This example contains client-side code that checks if the user authenticated successfully before
sending a command. The server-side code performs the authentication in one step, and executes
the command in a separate step.
CLIENT-SIDE (client.pl)
Example Language: Perl (Good)
$server = "server.example.com";
$username = AskForUserName();
$password = AskForPassword();
$address = AskForAddress();
$sock = OpenSocket($server, 1234);
writeSocket($sock, "AUTH $username $password\n");
$resp = readSocket($sock);
if ($resp eq "success") {
# username/pass is valid, go ahead and update the info!
writeSocket($sock, "CHANGE-ADDRESS $username $address\n";
}
else {
print "ERROR: Invalid Authentication!\n";
}
SERVER-SIDE (server.pl):
CWE Version 4.14
CWE-602: Client-Side Enforcement of Server-Side Security
CWE-602: Client-Side Enforcement of Server-Side Security