No matter how good is the design of a piece of software, the design corrodes proportional to the the time gathered the user requirements. As time goes by, the user requirements change. The design of the software become less oriented to the new user requirements. The programmers may feel the limitation of the original design. However, they have the stick with the design and trying to change the fewest thing to accomplish the goal - the user requirement.
Hence, cheap hacks and workarounds are introduced. These hacks and workarounds may not hurt the maintainability in short term. However, since the design may not consider the effect of these hacks and workarounds, some other factor may get affected. For example, security may get compromised.
Take XmlHttpRequest as and example, it is designed for retrieving XML or simple text data. However, people use it to retrieve JSON that allows executable JavaScript.
Even large enterprise applications are vulnerable to the corrosion. The architecture design of enterprise application is usually coarse grained due to the time and resource limitation in the business world. Hence, hacks and workarounds are very easy to introduced among a team of programmers. Since enterprise applications are large, it is not quite possible for the architects or the analysts to review the code. Thus, the design corrosions are easily occurred.
There is no easy solution to the phenomena. Adding extra resources may slow down the effect. However, it cannot be completely removed.