Most of the previous exploits are made possible due to poor coding practices during development. You should attempt to leverage these mistakes whenever you can. The following are examples of insecure coding practices. Note that these apply to most types of software, not just web apps:

  • Lack of input validation. This negligent practice alone is responsible for most of the injection and scripting attacks mentioned in this topic.
  • Hard-coded credentials. There are many ways these passwords could be exposed, including through SQL injection and XSS.
  • Storage and/or transmission of sensitive data in cleartext. You can sniff cleartext data transmitted over a network, or read exfiltrated cleartext data with minimal effort.
  • Unauthorized and/or insecure functions and unprotected APIs. Sometimes these functions and APIs are kept around for compatibility purposes, despite the security risk. You may be able to leverage the weaknesses in these functions/APIs.
  • Overly verbose errors. Whether intentional or not, some apps reveal a great deal about a code's structure and execution through error messages returned to the user. A simple form injection might return an SQL error revealing a table's column names, for example.
  • Lack of error handling. Although revealing too much in an error can be a problem, not handling errors at all is an even bigger problem. For example, an app may not respond gracefully to unexpected input, crashing the app or corrupting data.
  • Hidden elements. Just because an element is not immediately visible on the page doesn't mean you can't find it by exploring the page's code. In particular, you may be able to find sensitive data that is exposed in the page's DOM (i.e., the hierarchical tree-like structure of the HTML) but not displayed on the screen.
  • Verbose comments in source code. Comments are not meant to be truly hidden from the client, just suppressed in the marked-up page. Some developers forget this and include sensitive information in comments, such as server-side functionality, snippets of old code, and other information that can help you identify weak points or attack vectors.
  • Lack of code signing. Code that lacks a digital signature cannot be validated for its authenticity and integrity. It may be easier to inject malicious code into a running process when no mechanisms exist to compare that code against the authorized code.
  • Race conditions. These occur when the resulting outcome from execution processes is directly dependent on the order and timing of certain events. Issues arise if these events fail to execute in the order and timing intended by the developer. For example, an app can check that a file exists and then use it later. You may be able to replace the file after it is checked by the app but not yet used; this can trigger app instability or privilege escalation.