Сервер приложений ошибки PermGen, которые происходят после нескольких развертывания, скорее всего, вызывается ссылками, сохраненными контейнером в classloaders Ваших старых приложений. Например, использование пользовательского класса уровня журнала заставит ссылки быть сохраненными classloader сервера приложений. Можно обнаружить эти утечки inter-classloader при помощи современного (JDK6 +) аналитические инструменты JVM, такие как jmap и jhat для рассмотрения, какие классы продолжают быть сохраненными в приложении, и перепроектировании или устранении их использования. Обычные подозреваемые являются базами данных, регистраторами и другими библиотеками основного уровня платформы.
См. утечки Classloader: страшное "java.lang. OutOfMemoryError: PermGen располагают с интервалами" исключение , и особенно ответное письмо .
Используйте оба. Фактически, обратитесь к руководству, подобному шпаргалке по предотвращению OWASP XSS , о возможных случаях использования кодировки вывода и проверки ввода.
Проверка ввода помогает, когда вы не можете полагаться на кодировку вывода в определенных случаях. Например, вам лучше проверять входные данные, появляющиеся в URL-адресах, а не кодировать сами URL-адреса (Apache не будет обслуживать URL-адрес с кодировкой URL-адреса). Или, если на то пошло, проверяйте входные данные, которые появляются в выражениях JavaScript.
В конечном итоге поможет простое правило большого пальца - если вы недостаточно доверяете пользовательскому вводу или если вы подозреваете, что определенные источники могут привести к XSS-атакам, несмотря на кодировку вывода, проверьте это против белого списка.
Я предпочитаю кодировать все не буквенно-цифровые символы как числовые символы HTML. Поскольку почти, если не все атаки требуют неалфавитных символов (например, <, "и т. Д.), Это должно устранить большую часть опасного вывода.
Формат - & # N ;, где N - числовое значение символа ( вы можете просто преобразовать символ в int и объединить его со строкой, чтобы получить десятичное значение). Например:
// java-ish pseudocode StringBuffer safestrbuf = new StringBuffer(string.length()*4); foreach(char c : string.split() ){ if( Character.isAlphaNumeric(c) ) safestrbuf.append(c); else safestrbuf.append(""+(int)symbol);
Вам также необходимо убедиться, что вы кодируете непосредственно перед выводом в браузер, чтобы избежать двойного кодирования , или кодировка HTML, но отправка в другое место.
Обычной практикой является экранирование любых пользовательских данных во время повторного отображения в JSP, а не во время обработки отправил данные в сервлет или во время сохранения в БД. В JSP вы можете использовать JSTL (чтобы установить его, просто поместите jstl-1.2.jar в / WEB-INF / lib
)
или функцию fn: escapeXml
для этого. Например.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<p>Welcome <c:out value="${user.name}" /></p>
и
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<input name="username" value="${fn:escapeXml(param.username)}">
Вот и все. Нет необходимости в черном списке. Обратите внимание, что данные, управляемые пользователем, охватывают все , которые поступают по HTTP-запросу: параметры запроса, тело и заголовки (!!).
Если вы используете HTML-экранирование во время обработки представленных данных и / или сохранения в БД, то все это распространяется на бизнес-код и / или в базу данных.Это только проблемы с обслуживанием, и вы рискуете совершить двойной побег или даже больше, когда будете делать это в разных местах (например, &
превратится в &
вместо &
, так что конечный пользователь будет буквально видеть &
вместо &
в поле зрения. Бизнес-код и БД, в свою очередь, не чувствительны к XSS. Только представление. Вы должны избегать его только прямо там в поле зрения.