Шрифт:
Примеры из реальной жизни
Следующие примеры XSS–уязвимостей взяты из базы данных CVE (cve.mitre.org).
Уязвимость IBM Lotus Domino для атаки с кросс–сайтовым сценарием и внедрением HTML
По какой–то причине этому бюллетеню не присвоен номер в базе данных CVE. Противник может обойти HTML–кодирование в вычисляемом Lotus Notes значении, добавив квадратные скобки («[" и "]») в начало и конец поля для некоторых типов данных. Подробности на странице www.securityfocus.eom/bid/l 1458.
Ошибка при контроле входных данных в сценарии isqlplus, входящем в состав Oracle HTTP Server, позволяет удаленному пользователю провести атаку с кросс–сайтовым сценарием
И на этот раз у бюллетеня отсутствует номер. Oracle HTTP Server основан на сервере Apache 1.3.x. В сценарии isqlplus есть XSS–ошибка, связанная с недостаточным контролем значений параметров «action», «username» и «password». Атака может выглядеть примерно так:
http://[target]isqlplus?action=logon&username=xyzzy%22%3e%3cscript%3e
alert(\'XSS\')%3c/script%3e\&password=xyzzy%3cscript%3ealert(\'XSS\')%3c
/script%3e
Подробности на странице www.securitytracker.com/alerts/2004/Jan/1008838.html.
CVE–2002–0840
XSS–уязвимость на стандартной странице с сообщением об ошибке в Apache 2.0 до версии 2.0.43 и в Apache 1.3.x до версии 1.3.26. Подробности на странице http://cert.uni–stuttgart.de/archive/bugtraq/2002/10/msg00017.html.
Искупление греха
Путь к искуплению состоит из двух шагов:
1) не допускайте некорректных входных данных. Для проверки обычно применяются регулярные выражения;
2) при выводе данных применяйте HTML–кодирование.
Необходимо принимать обе эти меры предосторожности в своих программах. В приведенных ниже примерах показано, как это делается на практике.
Искупление греха в ISAPI–расширениях и фильтрах на C/C++
Во фрагменте ниже приведен код для HTML–кодирования информации, отправляемой браузеру.
/////////////////////////////////////////////////////////////////
// HtmlEncode
// Кодирует поток HTML-данных
// Аргументы
// strRaw: указатель на необработанные HTML-данные
// result: ссылка на результат, хранящийся в std::string
// Возвращаемое значение:
// false: не удалось закодировать HTML-данные
// true: все HTML-данные закодированы
bool HtmlEncode(char *strRaw, std::string &result) {
size_t iLen = 0;
size_t i = 0;
if (strRaw && (iLen = strlen(strRaw))) {
for (i = 0; i < iLen; i++)
switch(strRaw[i]) {
case \'\0\' : break;
case \'<\' : result.append("<"); break;
case \'>\' : result.append(">"); break;
case \'(\' : result.append("("); break;
case \')\' : result.append(")"); break;
case \'#\' : result.append("#"); break;
case \'&\' : result.append("&"); break;
case \'"\' : result.append("""); break;
default : result.append(1,strRaw[i]); break;
}
}
return i == iLen ? true : false;
}
Если вы хотите пользоваться регулярными выражениями в программах на C/C++, то обратите внимание на класс CAtlRegExp, предлагаемый Microsoft, или на библиотеку Boost.Regex, документированную на страницеlibs/regex/doc/syntax.html.
Искупление греха в ASP
Применяйте сочетание регулярных выражений (в данном случает объект RegExp в сценарии на VBScript) и HTML–кодирования для проверки входных данных:
<%
name = Request.QueryString("Name")
Set r = new ReqExp
r.Pattern = "^\w{5,25}$"
r.IgnoreCase = True
Set m = r.Execute(name)
If (len(m(0)) > 0) Then
Response.Write(Server.HTMLEncode(name))
End If
%>
Искупление греха в ASP. NET
Приведенный ниже код аналогичен предыдущему примеру, но для сопоставления с регулярным выражением и HTML–кодирования используется язык С# и библиотеки, входящие в каркас .NET Framework.
using System.Web; // Необходимо добавить ссылку на сборку System.Web.dll
private void btnSubmit_Click(object sender, System.EventArgs e)
{
Regex r = new Regex(@"^\w{5,25}");
if (r.Match(txtValue.Text).Success) {
Application.Lock;
Application.txtName.Text = txtValue.Text;
Application.UnLock;
lblName.Text = "Hello, " +
HttpUtility.HtmlEncode(txtName.Text);
} else {
lblName.Text = "Кто вы?";
}
}
Искупление греха в JSP
В JSP имеет смысл использовать нестандартный тег. Вот код тега, осуществляющего HTML–кодирование:
import java.IO.Exception;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class HtmlEncoderTag extends BodyTagSupport {
public HtmlEncoderTag {
super;
}
public int doAfterBody throws JspException {
if (bodyContent != null) {
System.out.println(bodyContent.getString);
String contents = bodyContent.getString;
String regExp = new String("^\\w{5,25}$");
// Сопоставить с регулярным выражением
if (contents.matches(regExp)) {
try {
bodyContent.getEnclosingWriter.write(contents);
} catch (IOException e) {
System.out.println("Ошибка ввода/вывода");
}
return EVAL_BODY_INCLUDE;
} else {
try {
bodyContent.getEnclosingWriter.write(encode(contents));
} catch (IOException e) {
System.out.println("Ошибка ввода/вывода");
}
System.out.println("Содержимое: " + contents.toString);
return EVAL_BODY_INCLUDE;
}
} else {
return EVAL_BODY_INCLUDE;
}
}
// В JSP нет функции для HTML-кодирования
public static String encode(String str) {
if (str == null)
return null;
StringBuffer s = new StringBuffer;
for (short i = 0; i < str.length; i++) {
char c = str.CharAt(i);
switch (c) {
case \'<\':
s.append("<");
break;
case \'>\':
s.append(">");
break;
case \'(\':
s.append("(");
break;
case \')\':
s.append(")");
break;
case \'#\':
s.append("#");
break;
case \'&\':
s.append("&");
break;
case \'"\':
s.append(""");
break;
default:
s.append(c);
}
}
return s.toString;
}
}