Security is proactive, not reactive. Developers do not get the opportunity to watch opponent's movements so that they can react to them, like they could in a sword fight or a chess match.
Developers should assume their systems will be attacked and then figure out how it will happen and how to prevent it ahead of time. It is a "mystery in reverse".
A hacker's best attack avenue is the unexpected one--to walk through the door that is not being watched. Often this means probing a system looking for mistakes or poor assumptions made by the developer.
The best way to close these avenues is to do a complete security review and to be constantly mindful of security. It is helpful to think about what assumptions have been made and to challenge those assumptions.
Many times security weaknesses lie in "edge cases". Developers often code for the path through the application that users are expected to take. They must also consider the out-of-the-ordinary possibilities as well. Common examples include unexpected characters, control or escape characters for various programming languages, and race conditions.
For example, imagine a form with a text input field for a city name. The expected path, sometimes called the "happy path", is for the user to enter their city name.
A sample of edge cases to consider might include:
It is important to consider all possible avenues of attack. Writing software tests can provide reassurance that considered vulnerabilities have been adequately addressed.
Staying informed about Common Vulnerabilities and Exposures (CVE) and the attack vectors being recently experienced by others will be helpful in planning defenses.