Как послать электронное письмо HTML перспективе от Java

Когда в статьях рассказывается о параметризованных запросах, останавливающих атаки SQL, они на самом деле не объясняют, почему это часто бывает так: «Это так, поэтому не спрашивайте, почему» - возможно, потому что они сами не знают. Верным признаком плохого педагога является тот, который не может признать, что он ничего не знает. Но я отвлекся. Когда я говорю, я понял, что совершенно понятно, что меня путают просто. Представьте себе динамический SQL-запрос

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

, поэтому простая инсталляция sql должна была просто ввести имя пользователя в качестве «OR 1 = 1». Это действительно сделало бы запрос sql:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

В этом заявлении указывается, что все клиенты, где они являются, являются пустыми ('') или 1 = 1, что является логическим, приравнивая true. Затем он использует - чтобы прокомментировать остальную часть запроса. Таким образом, это будет просто распечатывать всю таблицу клиентов или делать с ней все, что вы захотите, если он войдет в систему, он войдет в систему с привилегиями первого пользователя, которые часто могут быть администратором.

Теперь параметризованные запросы делайте это по-другому, с кодом типа:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

parameters.add("User", username)
parameters.add("Pass", password)

, где имя пользователя и пароль являются переменными, указывающими на связанное введенное имя пользователя и пароль

. Теперь вы можете думать, что это ничего не меняет. Конечно, вы все равно могли бы просто ввести в поле имени пользователя что-то вроде Nobody OR 1 = 1 '-, эффективно выполнив запрос:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

И это похоже на действительный аргумент. Но вы ошибаетесь.

Способ работы с параметризованными запросами заключается в том, что sqlQuery отправляется как запрос, и база данных точно знает, что будет делать этот запрос, и только после этого он будет вставлять имя пользователя и пароли просто как ценности. Это означает, что они не могут выполнить запрос, потому что база данных уже знает, что будет делать запрос. Таким образом, в этом случае он будет искать имя пользователя «Nobody OR 1 = 1 '-» и пустой пароль, который должен выглядеть ложным.

Это не полное решение, хотя и вход валидация все равно потребуется, так как это не повлияет на другие проблемы, такие как атаки XSS, поскольку вы все равно можете поместить javascript в базу данных. Затем, если это зачитано на странице, оно будет отображать его как обычный javascript, в зависимости от какой-либо проверки валидации. Так что лучше всего по-прежнему использовать проверку ввода, но используя параметризованные запросы или хранимые процедуры, чтобы остановить любые атаки SQL.

18
задан Stephane Grenier 26 November 2008 в 21:53
поделиться

6 ответов

После большого расследования я смог сделать некоторые значительные успехи.

Во-первых, вместо того, чтобы использовать JavaMail непосредственно, я рекомендую использовать Джакартская библиотека Commons Email . Это действительно упрощает проблему много!

код теперь:

HtmlEmail email = new HtmlEmail();

email.setHostName(mailserver);
email.setAuthentication(username, password);
email.setSmtpPort(port);
email.setFrom(fromEmail);
email.addTo(to);
email.setSubject(subject);

email.setTextMsg(textBody);
email.setHtmlMsg(htmlBody);

email.setDebug(true);

email.send();

Разговор о простом.

Однако существует все еще проблема. Версия HTML электронной почты работает отлично в Gmail, Hotmail, и т.д. Но это все еще правильно не отобразится в Outlook. Это всегда хочет отобразить текстовую версию, и я не уверен почему. Я подозреваю, что это - установка в Outlook, но я не могу найти его...

16
ответ дан 30 November 2019 в 07:50
поделиться

В дополнение к удалению эти html.setHeader("Content-Type", html.getContentType()) вызов, как уже предполагают, я заменил бы строку:

MimeMultipart content = new MimeMultipart();

… с:

MimeMultipart content = new MimeMultiPart("alternative");

… и удаление строки:

message.setHeader("Content-Type" , content.getContentType() );

конструктор MimeMultiPart по умолчанию мог вызывать проблемы с "многослойным/смешанным" типом контента.

При использовании многослойный/альтернативный, альтернативы заказаны тем, насколько верный они к оригиналу с лучшим представлением в последний раз. Однако клиенты обычно дают пользователям опцию отобразить простой текст, даже когда HTML присутствует. Вы уверены, что эта опция не включена в Outlook? Как делают другие агенты пользователя, как Thunderbird или Gmail, рассматривают Ваши сообщения?

кроме того, удостоверьтесь, что HTML правильно построен. Я проверил бы содержимое HTML с сервис проверки W3 , и возможно сохранил бы его в файл и просмотрел бы его с различными версиями IE также. Возможно, существует дефект, там заставляющий Outlook отступить к простому тексту.

5
ответ дан 30 November 2019 в 07:50
поделиться
html.setContent(htmlBody, "text/html");
html.setHeader("MIME-Version" , "1.0" );
html.setHeader("Content-Type" , html.getContentType() );

setContent и setHeader("Content-Type", String) делают то же самое - действительно ли возможно, что html.getContentType() возвращает что-то другое, чем text/html?

Расширение на основе комментария и @PhilLho & ответ @erickson (geez, я должен медленно вводить), используйте:

MimeMultipart content = new MimeMultipart("alternative")
3
ответ дан 30 November 2019 в 07:50
поделиться

Необходимо посмотреть на источник полученного сообщения: является многослойным/альтернативным Тип контента сообщения?

1
ответ дан 30 November 2019 в 07:50
поделиться

решение для workaroung решило перспективу 2003: Это сообщение использует набор символов, который не поддерживается интернет-сервисом. не отображается правильно.

Это могло произойти из-за кодирования. Большинство страниц HTML использует iso-8859-1 не попытка CP 1252, изменяющаяся

, Например, Ваш код:

message.setContent(sBuffer.toString(), "text/html");

Изменение это к:

message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=\"iso-8859-1\"");

Это бросает новую контролируемую исключительную ситуацию: java.io. UnsupportedEncodingException, таким образом, необходимо объявить, что это брошено, или поймать его. iso-8859-1 поддерживается так, исключение никогда не будет выдаваться, если что-то не будет повреждено с Вашим rt.jar.

С уважением, Javeed javeed.mca@gmail.com

0
ответ дан 30 November 2019 в 07:50
поделиться

Измените это к:

message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=\"iso-8859-1\"");

Набор Content Char. Должно быть:

message.setContent(sBuffer.toString(), "text/html;charset=iso-8859-1");
3
ответ дан 30 November 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: