var yamlString = getYAMLFromUser();
// Setup the input
var input = new StringReader(yamlString);
// Load the stream
var yaml = new YamlStream();
yaml.Load(input);
var yaml = require('js-yaml');
var untrusted_yaml = getYAMLFromUser();
yaml.load(untrusted_yaml)
import yaml
yamlString = getYamlFromUser()
yaml.load(yamlString)
예제 2: 다음 ASPX 코드는 Microsoft Ajax CDN에 대한 모든 ASP.NET 프레임워크 스크립트 요청의 자동 리디렉션을 활성화합니다.
...
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js" type="text/javascript"></script>
...
...
<asp:ScriptManager
ID="ScriptManager1"
EnableCdn="true"
Runat="Server" />
...
Example 2
에서 ScriptManager
제어는 해당 ASPX 페이지를 구성하여 적절한 CDN에 대한 임의의 스크립트 요청을 자동으로 리디렉션합니다.=cmd|'/C calc.exe'!Z0
. 스프레드시트를 여는 사용자가 문서의 출처를 신뢰하는 경우, 스프레드시트 프로세서에서 제시하는 모든 보안 프롬프트를 수락하고 해당 시스템에서 페이로드(이 예제에서는 Windows 계산기를 열고 있음)가 실행될 수 있게 할 수 있습니다.
public void Service()
{
string name = HttpContext.Request["name"];
string data = GenerateCSVFor(name);
HttpContext.Response.Clear();
HttpContext.Response.Buffer = true;
HttpContext.Response.AddHeader("content-disposition", "attachment;filename=file.csv");
HttpContext.Response.Charset = "";
HttpContext.Response.ContentType = "application/csv";
HttpContext.Response.Output.Write(tainted);
HttpContext.Response.Flush();
HttpContext.Response.End();
}
=cmd|'/C calc.exe'!Z0
. 스프레드시트를 여는 사용자가 문서의 출처를 신뢰하는 경우, 스프레드시트 프로세서에서 제시하는 모든 보안 프롬프트를 수락하고 해당 시스템에서 페이로드(이 예제에서는 Windows 계산기를 열고 있음)가 실행될 수 있게 할 수 있습니다.
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
foo := r.FormValue("foo")
...
w := csv.NewWriter(file)
w.Write(foo)
}
=cmd|'/C calc.exe'!Z0
. 스프레드시트를 여는 사용자가 문서의 출처를 신뢰하는 경우, 스프레드시트 프로세서에서 제시하는 모든 보안 프롬프트를 수락하고 해당 시스템에서 페이로드(이 예제에서는 Windows 계산기를 열고 있음)가 실행될 수 있게 할 수 있습니다.
@RequestMapping(value = "/api/service.csv")
public ResponseEntity<String> service(@RequestParam("name") String name) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "application/csv; charset=utf-8");
responseHeaders.add("Content-Disposition", "attachment;filename=file.csv");
String data = generateCSVFor(name);
return new ResponseEntity<>(data, responseHeaders, HttpStatus.OK);
}
=cmd|'/C calc.exe'!Z0
. 스프레드시트를 여는 사용자가 문서의 출처를 신뢰하는 경우, 스프레드시트 프로세서에서 제시하는 모든 보안 프롬프트를 수락하고 해당 시스템에서 페이로드(이 예제에서는 Windows 계산기를 열고 있음)가 실행될 수 있게 할 수 있습니다.
@RequestMapping(value = "/api/service.csv")
fun service(@RequestParam("name") name: String): ResponseEntity<String> {
val responseHeaders = HttpHeaders()
responseHeaders.add("Content-Type", "application/csv; charset=utf-8")
responseHeaders.add("Content-Disposition", "attachment;filename=file.csv")
val data: String = generateCSVFor(name)
return ResponseEntity(data, responseHeaders, HttpStatus.OK)
}
services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>();
app.use('/graphql', graphqlHTTP({
schema
}));
app.add_url_rule('/graphql', view_func=GraphQLView.as_view(
'graphql',
schema = schema
))
Metadata
개체가 생성됩니다. 그러므로 공격자가 중요한 프로토콜 필드를 제어하게 될 수 있습니다.Metadata
클래스는 Google Remote Procedure Call(gRPC)에서 사용하는 기본 프로토콜의 헤더 데이터를 저장하는 데 사용되는 경우가 많습니다. 기본 프로토콜이 HTTP일 때는 Metadata
개체의 데이터를 제어하면 시스템이 HTTP 헤더 조작에 취약해질 수 있습니다. 공격자가 다른 공격 벡터(대개 기본 프로토콜 기반)를 이용할 수 있기 때문입니다.Metadata
개체의 입력으로 사용되는 신뢰할 수 없는 데이터를 보여줍니다.
...
String? evnVar = System.Environment.GetEnvironmentVariable("evnVar ");
Metadata headers = new Metadata();
headers.Add("field", evnVar);
CallOptions callOptions = new CallOptions(headers);
...
Metadata
개체가 생성됩니다. 그러므로 공격자가 중요한 프로토콜 필드를 제어하게 될 수도 있습니다.Metadata
클래스는 Google Remote Procedure Call(gRPC)에서 사용하는 기본 프로토콜의 헤더 데이터를 저장하는 데 사용되는 경우가 많습니다. 기본 프로토콜이 HTTP일 때는 Metadata
개체의 데이터를 제어하면 시스템이 HTTP 헤더 조작에 취약해질 수 있습니다. 공격자가 다른 공격 벡터(대개 기본 프로토콜 기반)를 이용할 수 있기 때문입니다.Metadata
개체의 입력으로 사용되는 사용자 제어 가능 데이터를 보여줍니다.
...
String badData = getUserInput();
Metadata headers = new Metadata();
headers.put(Metadata.Key.of("sample", Metadata.ASCII_STRING_MARSHALLER), badData);
...
author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
author = request->get_form_field( 'author' ).
response->set_cookie( name = 'author' value = author ).
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 Cookie Manipulation 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.
@HttpGet
global static void doGet() {
...
Map<String, String> params = ApexPages.currentPage().getParameters();
RestResponse res = RestContext.response;
res.addHeader(params.get('name'), params.get('value'));
...
}
author
및 Jane Smith
로 구성되어 있다고 가정할 때 이 헤더를 포함하는 HTTP 응답은 다음과 같은 형식일 수 있습니다.
HTTP/1.1 200 OK
...
author:Jane Smith
...
HTTP/1.1 200 OK\r\n...foo
및 bar
와 같은 악성 이름/값 쌍을 전송할 수 있습니다. 그러면 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
HTTP/1.1 200 OK
...
foo:bar
HttpResponse.AddHeader()
메서드로 보낼 때 %0d, %0a 및 %00으로 변환합니다. 새 줄 문자로 헤더를 설정하지 못하도록 방지하는 최신 .NET 프레임워크를 사용한다면, 응용 프로그램은 HTTP Response Splitting에 취약하지 않을 수도 있습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
protected System.Web.UI.WebControls.TextBox Author;
...
string author = Author.Text;
Cookie cookie = new Cookie("author", author);
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
Author.Text
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
EXEC CICS
WEB READ
FORMFIELD(NAME)
VALUE(AUTHOR)
...
END-EXEC.
EXEC CICS
WEB WRITE
HTTPHEADER(COOKIE)
VALUE(AUTHOR)
...
END-EXEC.
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
<cfcookie name = "author"
value = "#Form.author#"
expires = "NOW">
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1/1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 Cookie Manipulation 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final headers = request.headers;
final contentType = headers.value('content-type');
final client = HttpClient();
final clientRequest = await client.getUrl(Uri.parse('https://example.com'));
clientRequest.headers.add('Content-Type', contentType as Object);
});
author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
author := request.FormValue("AUTHOR_PARAM")
cookie := http.Cookie{
Name: "author",
Value: author,
Domain: "www.example.com",
}
http.SetCookie(w, &cookie)
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
String author = request.getParameter(AUTHOR_PARAM);
...
Cookie cookie = new Cookie("author", author);
cookie.setMaxAge(cookieExpiration);
response.addCookie(cookie);
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
author = form.author.value;
...
document.cookie = "author=" + author + ";expires="+cookieExpiration;
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.name
및 value
가 공격자에 의해 제어될 수 있다고 가정합니다. 코드는 이름 및 값이 공격자에 의해 제어될 수 있는 HTTP 헤더를 설정합니다.
...
NSURLSessionConfiguration * config = [[NSURLSessionConfiguration alloc] init];
NSMutableDictionary *dict = @{};
[dict setObject:value forKey:name];
[config setHTTPAdditionalHeaders:dict];
...
author
및 Jane Smith
로 구성되었다고 가정하면 이 헤더가 포함된 HTTP 응답의 형식은 다음과 같을 수 있습니다.
HTTP/1.1 200 OK
...
author:Jane Smith
...
HTTP/1.1 200 OK\r\n...foo
및 bar
와 같은 악의적인 이름/값 쌍을 제출할 수 있고 그러면 HTTP 응답이 다음 형식의 두 응답으로 분할됩니다.
HTTP/1.1 200 OK
...
HTTP/1.1 200 OK
...
foo:bar
header()
함수에 전달될 때 경고를 생성하고 헤더 생성을 중단합니다. 사용 중인 PHP 버전이 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.
<?php
$location = $_GET['some_location'];
...
header("location: $location");
?>
HTTP/1.1 200 OK
...
location: index.html
...
some_location
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "index.html\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
location: index.html
HTTP/1.1 200 OK
...
author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
-- Assume QUERY_STRING looks like AUTHOR_PARAM=Name
author := SUBSTR(OWA_UTIL.get_cgi_env('QUERY_STRING'), 14);
OWA_UTIL.mime_header('text/html', false);
OWA_COOKE.send('author', author);
OWA_UTIL.http_header_close;
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
location = req.field('some_location')
...
response.addHeader("location",location)
HTTP/1.1 200 OK
...
location: index.html
...
some_location
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "index.html\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
location: index.html
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 사이트의 다른 부분에 대한 get 요청에 사용합니다.
author = req.params[AUTHOR_PARAM]
http = Net::HTTP.new(URI("http://www.mysite.com"))
http.post('/index.php', "author=#{author}")
POST /index.php HTTP/1.1
Host: www.mysite.com
author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nPOST /index.php HTTP/1.1\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
POST /index.php HTTP/1.1
Host: www.mysite.com
author=Wiley Hacker
POST /index.php HTTP/1.1
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.name
및 value
가 공격자에 의해 제어될 수 있다고 가정합니다. 코드는 이름 및 값이 공격자에 의해 제어될 수 있는 HTTP 헤더를 설정합니다.
...
var headers = []
headers[name] = value
let config = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.acme")
config.HTTPAdditionalHeaders = headers
...
author
및 Jane Smith
로 구성되었다고 가정하면 이 헤더가 포함된 HTTP 응답의 형식은 다음과 같을 수 있습니다.
HTTP/1.1 200 OK
...
author:Jane Smith
...
HTTP/1.1 200 OK\r\n...foo
및 bar
와 같은 악의적인 이름/값 쌍을 제출할 수 있고 그러면 HTTP 응답이 다음 형식의 두 응답으로 분할됩니다.
HTTP/1.1 200 OK
...
HTTP/1.1 200 OK
...
foo:bar
author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
author = Request.Form(AUTHOR_PARAM)
Response.Cookies("author") = author
Response.Cookies("author").Expires = cookieExpiration
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
author = request->get_form_field( 'author' ).
response->set_cookie( name = 'author' value = author ).
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 Cookie Manipulation 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
Cookie cookie = new Cookie('author', author, '/', -1, false);
ApexPages.currentPage().setCookies(new Cookie[] {cookie});
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
author
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."와 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
protected System.Web.UI.WebControls.TextBox Author;
...
string author = Author.Text;
Cookie cookie = new Cookie("author", author);
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
<cfcookie name = "author"
value = "#Form.author#"
expires = "NOW">
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 Cookie Manipulation 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
author := request.FormValue("AUTHOR_PARAM")
cookie := http.Cookie{
Name: "author",
Value: author,
Domain: "www.example.com",
}
http.SetCookie(w, &cookie)
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."와 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
String author = request.getParameter(AUTHOR_PARAM);
...
Cookie cookie = new Cookie("author", author);
cookie.setMaxAge(cookieExpiration);
response.addCookie(cookie);
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
Example 1
을 Android 플랫폼에 맞게 조정합니다.교차 사용자 변조(cross-user defacement): 공격자는 피해 서버에 하나의 요청을 보낼 수 있게 되어 서버가 두 개의 응답을 만들게 하는데 두 번째 응답은 다른 요청에 대한 응답으로 잘못 해석될 수 있습니다. 이를테면, 서버와 같은 TCP 연결을 공유하는 다른 사용자의 요청에 대한 응답으로 해석됩니다. 이는 사용자를 속여 악성 요청을 사용자 스스로 전송하게 하거나 공유 프록시 서버처럼 공격자와 사용자가 서버에 대한 하나의 TCP 연결을 공유하는 경우 원격으로 전송하도록 합니다. 공격자가 이 능력을 이용하여 사용자가 응용 프로그램이 해킹당했다고 믿게 만들고 응용 프로그램 보안에 대한 자신감을 상실하게 만드는 정도면 다행이라고 할 수 있습니다. 최악의 경우, 공격자는 응용 프로그램 동작을 모방하여 계정 번호와 암호 등의 개인 정보를 공격자에게 리디렉션하는 특별히 제작된 콘텐트를 이용하기도 합니다.
...
CookieManager webCookieManager = CookieManager.getInstance();
String author = this.getIntent().getExtras().getString(AUTHOR_PARAM);
String setCookie = "author=" + author + "; max-age=" + cookieExpiration;
webCookieManager.setCookie(url, setCookie);
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
author = form.author.value;
...
document.cookie = "author=" + author + ";expires="+cookieExpiration;
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
<?php
$author = $_GET['AUTHOR_PARAM'];
...
header("author: $author");
?>
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
location = req.field('some_location')
...
response.addHeader("location",location)
HTTP/1.1 200 OK
...
location: index.html
...
some_location
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "index.html\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
location: index.html
HTTP/1.1 200 OK
...
IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 Cookie Manipulation 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.IllegalArgumentException
을 발생시킵니다. 응용 프로그램 서버가 새 줄 문자로 헤더를 설정하는 것을 방해한다면, 해당 응용 프로그램은 HTTP Response Splitting에 취약하지 않습니다. 그러나, 단지 새 줄 문자에 대한 필터링은 쿠키 조작 또는 Open Redirection에 대해 응용 프로그램을 취약하게 남겨둘 수 있기 때문에 사용자 입력으로 HTTP 헤더를 설정할 때는 여전히 주의해야 합니다.author
를 읽어들여 HTTP 응답의 쿠키 헤더에 설정합니다.
...
author = Request.Form(AUTHOR_PARAM)
Response.Cookies("author") = author
Response.Cookies("author").Expires = cookieExpiration
...
HTTP/1.1 200 OK
...
Set-Cookie: author=Jane Smith
...
AUTHOR_PARAM
에 전송된 값에 CR 및 LF 문자가 들어 있지 않을 때에만 이 형식을 유지합니다. 공격자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..."과 같은 악성 문자열을 전송하는 경우 HTTP 응답은 다음과 같이 두 개의 응답으로 나누어집니다.
HTTP/1.1 200 OK
...
Set-Cookie: author=Wiley Hacker
HTTP/1.1 200 OK
...
HtmlInputHidden hidden = new HtmlInputHidden();
Hidden hidden = new Hidden(element);
hidden
형식의 <input>
태그는 숨겨진 필드를 사용하고 있음을 나타냅니다.
<input type="hidden">
X-XSS-Protection
헤더는 최신 브라우저에서 기본적으로 활성화됩니다. 이 헤더 값을 false(0)로 설정하면 Cross-Site Scripting 보호가 비활성화됩니다.X-XSS-Protection
헤더가 명시적으로 비활성화되어 있어 Cross-Site Scripting 공격의 위험이 증가할 수 있습니다.X-XSS-Protection
헤더는 최신 브라우저에서 기본적으로 활성화됩니다. 이 헤더 값을 false(0)로 설정하면 Cross-Site Scripting 보호가 비활성화됩니다.
<http auto-config="true">
...
<headers>
...
<xss-protection xss-protection-enabled="false" />
</headers>
</http>
X-XSS-Protection
헤더가 명시적으로 비활성화되어 있어 cross-site scripting 공격의 위험이 증가할 수 있습니다.X-XSS-Protection
헤더는 최신 브라우저에서 기본적으로 활성화됩니다. 이 헤더 값을 false(0)로 설정하면 Cross-Site Scripting 보호가 비활성화됩니다.X-XSS-Protection
헤더가 명시적으로 비활성화되어 있어 cross-site scripting 공격의 위험이 증가할 수 있습니다.X-XSS-Protection
헤더는 최신 브라우저에서 기본적으로 활성화됩니다. 이 헤더 값을 false(0)로 설정하면 Cross-Site Scripting 보호가 비활성화됩니다.Application_BeginRequest
메서드가 비어 있거나 X-Content-Type-Options
를 nosniff
로 설정하는 함수 호출을 포함하지 않거나 해당 헤더를 제거하려고 합니다.X-Content-Type-Options: nosniff
라는 HTTP 헤더를 사용해야 합니다.X-Content-Type-Options
를 nosniff
로 설정하지 않습니다.X-Content-Type-Options: nosniff
를 사용합니다.net.http.DetectContentType()
을 사용하여 응답 Content-Type을 결정합니다.
...
resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
content_type := DetectContentType(body)
...
X-Content-Type-Options
를 nosniff
로 설정하거나 이 보안 헤더를 명시적으로 비활성화하지 않습니다.X-Content-Type-Options: nosniff
라는 HTTP 헤더를 사용해야 합니다.
<http auto-config="true">
...
<headers>
...
<content-type-options disabled="true"/>
</headers>
</http>
X-Content-Type-Options
를 nosniff
로 설정하거나 이 보안 헤더를 명시적으로 비활성화하지 않습니다.X-Content-Type-Options: nosniff
라는 HTTP 헤더를 사용해야 합니다.X-Content-Type-Options
를 nosniff
로 설정하거나 이 보안 헤더를 명시적으로 비활성화하지 않습니다.X-Content-Type-Options: nosniff
라는 HTTP 헤더를 사용해야 합니다.Access-Control-Allow-Origin
이라는 새 HTTP 헤더가 정의될 경우 JavaScript가 도메인 전체의 데이터에 액세스할 수 있습니다. 이 헤더가 있는 경우, 웹 서버는 cross-origin 요청을 사용하여 해당 도메인에 액세스할 수 있는 다른 도메인을 정의합니다. 그러나, 지나치게 허용적인 CORS 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 헤더 정의 시 주의해야 합니다.
Response.AppendHeader("Access-Control-Allow-Origin", "*");
*
를 Access-Control-Allow-Origin
헤더의 값으로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 실행 중인 JavaScript에 접근할 수 있음을 나타냅니다.Access-Control-Allow-Origin
이라는 새 HTTP 헤더가 정의될 경우 JavaScript가 도메인 전체의 데이터에 액세스할 수 있습니다. 이 헤더가 있는 경우, 웹 서버는 cross-origin 요청을 사용하여 해당 도메인에 액세스할 수 있는 다른 도메인을 정의합니다. 그러나, 지나치게 허용적인 CORS 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 헤더 정의 시 주의해야 합니다.
<websocket:handlers allowed-origins="*">
<websocket:mapping path="/myHandler" handler="myHandler" />
</websocket:handlers>
*
를 Access-Control-Allow-Origin
헤더의 값으로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 실행 중인 JavaScript에 접근할 수 있음을 나타냅니다.Access-Control-Allow-Origin
이라는 새 HTTP 헤더가 정의될 경우 JavaScript가 도메인 전체의 데이터에 액세스할 수 있습니다. 이 헤더가 있는 경우, 웹 서버는 cross-origin 요청을 사용하여 해당 도메인에 액세스할 수 있는 다른 도메인을 정의합니다. 그러나, 지나치게 허용적인 CORS 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 헤더 정의 시 주의해야 합니다.
<?php
header('Access-Control-Allow-Origin: *');
?>
*
를 Access-Control-Allow-Origin
헤더의 값으로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 실행 중인 JavaScript에 접근할 수 있음을 나타냅니다.Access-Control-Allow-Origin
이라는 새 HTTP 헤더가 정의될 경우 JavaScript가 도메인 전체의 데이터에 액세스할 수 있습니다. 이 헤더가 있는 경우, 웹 서버는 cross-origin 요청을 사용하여 해당 도메인에 액세스할 수 있는 다른 도메인을 정의합니다. 그러나, 지나치게 허용적인 CORS 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 헤더 정의 시 주의해야 합니다.
response.addHeader("Access-Control-Allow-Origin", "*")
*
를 Access-Control-Allow-Origin
헤더의 값으로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 실행 중인 JavaScript에 접근할 수 있음을 나타냅니다.Access-Control-Allow-Origin
이라는 새 HTTP 헤더가 정의될 경우 JavaScript가 도메인 전체의 데이터에 액세스할 수 있습니다. 이 헤더가 있는 경우, 웹 서버는 cross-origin 요청을 사용하여 해당 도메인에 액세스할 수 있는 다른 도메인을 정의합니다. 그러나, 지나치게 허용적인 CORS 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 헤더 정의 시 주의해야 합니다.
play.filters.cors {
pathPrefixes = ["/some/path", ...]
allowedOrigins = ["*"]
allowedHttpMethods = ["GET", "POST"]
allowedHttpHeaders = ["Accept"]
preflightMaxAge = 3 days
}
*
를 Access-Control-Allow-Origin
헤더의 값으로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 실행 중인 JavaScript에 액세스할 수 있음을 나타냅니다.Access-Control-Allow-Origin
이라는 새 HTTP 헤더가 정의될 경우 JavaScript가 도메인 전체의 데이터에 액세스할 수 있습니다. 이 헤더가 있는 경우, 웹 서버는 cross-origin 요청을 사용하여 해당 도메인에 액세스할 수 있는 다른 도메인을 정의합니다. 그러나, 지나치게 허용적인 CORS 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 헤더 정의 시 주의해야 합니다.
Response.AddHeader "Access-Control-Allow-Origin", "*"
*
를 Access-Control-Allow-Origin
헤더의 값으로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 실행 중인 JavaScript에 접근할 수 있음을 나타냅니다.
...
String lang = Request.Form["lang"];
WebClient client = new WebClient();
client.BaseAddress = url;
NameValueCollection myQueryStringCollection = new NameValueCollection();
myQueryStringCollection.Add("q", lang);
client.QueryString = myQueryStringCollection;
Stream data = client.OpenRead(url);
...
en&poll_id=1
같은 lang
을 제공할 가능성을 고려하지 않았기 때문에 공격자는 마음대로 poll_id
를 변경할 수 있게 됩니다.
...
String lang = request.getParameter("lang");
GetMethod get = new GetMethod("http://www.example.com");
get.setQueryString("lang=" + lang + "&poll_id=" + poll_id);
get.execute();
...
en&poll_id=1
같은 lang
을 제공할 가능성을 고려하지 않았기 때문에 공격자는 마음대로 poll_id
를 변경할 수 있게 됩니다.
<%
...
$id = $_GET["id"];
header("Location: http://www.host.com/election.php?poll_id=" . $id);
...
%>
name=alice
를 지정했지만 name=alice&
를 더 추가했으며, 첫 번째 것을 가져오는 서버에서 이것이 사용되면 alice
로 가장하여 이 사용자의 계정에 대한 추가 정보를 획득할 수 있습니다.
<authorization>
<allow verbs="GET,POST" users="admin"/>
<deny verbs="GET,POST"users="*" />
</authorization>
<security-constraint>
<display-name>Admin Constraint</display-name>
<web-resource-collection>
<web-resource-name>Admin Area</web-resource-name>
<url-pattern>/pages/index.jsp</url-pattern>
<url-pattern>/admin/*.do</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>only admin</description>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<http-method>
태그에 명시적으로 정의되지 않으므로 HEAD 요청으로 GET 또는 POST 요청을 대신하여 관리 기능이 수행 가능합니다. 관리 기능을 실행하기 위한 HEAD 요청의 경우 조건 3이 유지되어야 합니다. 즉, 응용 프로그램이 POST 이외의 동사를 기반으로 명령을 수행해야 합니다. 일부 웹/응용 프로그램 서버는 임의의 비표준 HTTP verb를 허용하고 GET 요청을 받은 것처럼 응답합니다. 그런 경우, 공격자는 요청에서 임의의 verb를 사용하여 관리 페이지를 볼 수 있습니다.
GET /admin/viewUsers.do HTTP/1.1
Host: www.example.com
FOO /admin/viewUsers.do HTTP/1.1
Host: www.example.com
FORM GenerateReceiptURL CHANGING baseUrl TYPE string.
DATA: r TYPE REF TO cl_abap_random,
var1 TYPE i,
var2 TYPE i,
var3 TYPE n.
GET TIME.
var1 = sy-uzeit.
r = cl_abap_random=>create( seed = var1 ).
r->int31( RECEIVING value = var2 ).
var3 = var2.
CONCATENATE baseUrl var3 ".html" INTO baseUrl.
ENDFORM.
CL_ABAP_RANDOM->INT31
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. CL_ABAP_RANDOM
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
string GenerateReceiptURL(string baseUrl) {
Random Gen = new Random();
return (baseUrl + Gen.Next().toString() + ".html");
}
Random.Next()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Random.Next()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
char* CreateReceiptURL() {
int num;
time_t t1;
char *URL = (char*) malloc(MAX_URL);
if (URL) {
(void) time(&t1);
srand48((long) t1); /* use time to set seed */
sprintf(URL, "%s%d%s", "http://test.com/", lrand48(), ".html");
}
return URL;
}
lrand48()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. lrand48()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 디자인에도 결함이 있지만 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용하는 것이 보다 안전했을 것입니다.
<cfoutput>
Receipt: #baseUrl##Rand()#.cfm
</cfoutput>
Rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
import "math/rand"
...
var mathRand = rand.New(rand.NewSource(1))
rsa.GenerateKey(mathRand, 2048)
rand.New()
함수를 사용하여 RSA 키의 무작위성을 생성합니다. rand.New()
는 통계적 PRNG이므로 생성되는 값을 공격자가 쉽게 추측할 수 있습니다.
String GenerateReceiptURL(String baseUrl) {
Random ranGen = new Random();
ranGen.setSeed((new Date()).getTime());
return (baseUrl + ranGen.nextInt(400000000) + ".html");
}
Random.nextInt()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Random.nextInt()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
function genReceiptURL (baseURL){
var randNum = Math.random();
var receiptURL = baseURL + randNum + ".html";
return receiptURL;
}
Math.random()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Math.random()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
fun GenerateReceiptURL(baseUrl: String): String {
val ranGen = Random(Date().getTime())
return baseUrl + ranGen.nextInt(400000000).toString() + ".html"
}
Random.nextInt()
함수를 사용하여 생성하는 영수증 페이지에 대해 "고유한" 식별자를 생성합니다. Random.nextInt()
는 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추측할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 식별자를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
function genReceiptURL($baseURL) {
$randNum = rand();
$receiptURL = $baseURL . $randNum . ".html";
return $receiptURL;
}
rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
CREATE or REPLACE FUNCTION CREATE_RECEIPT_URL
RETURN VARCHAR2
AS
rnum VARCHAR2(48);
time TIMESTAMP;
url VARCHAR2(MAX_URL)
BEGIN
time := SYSTIMESTAMP;
DBMS_RANDOM.SEED(time);
rnum := DBMS_RANDOM.STRING('x', 48);
url := 'http://test.com/' || rnum || '.html';
RETURN url;
END
DBMS_RANDOM.SEED()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. DBMS_RANDOM.SEED()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 디자인에도 결함이 있지만 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용하는 것이 보다 안전했을 것입니다.
def genReceiptURL(self,baseURL):
randNum = random.random()
receiptURL = baseURL + randNum + ".html"
return receiptURL
rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
def generateReceiptURL(baseUrl) {
randNum = rand(400000000)
return ("#{baseUrl}#{randNum}.html");
}
Kernel.rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Kernel.rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다.
def GenerateReceiptURL(baseUrl : String) : String {
val ranGen = new scala.util.Random()
ranGen.setSeed((new Date()).getTime())
return (baseUrl + ranGen.nextInt(400000000) + ".html")
}
Random.nextInt()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Random.nextInt()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
sqlite3_randomness(10, &reset_token)
...
Function genReceiptURL(baseURL)
dim randNum
randNum = Rnd()
genReceiptURL = baseURL & randNum & ".html"
End Function
...
Rnd()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Rnd()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
...
private bool CertificateCheck(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
...
return true;
}
...
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create("https://www.myTrustedSite.com");
webRequest.ServerCertificateValidationCallback = CertificateCheck;
WebResponse response = webRequest.GetResponse();
...
...
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
...
...
config := &tls.Config{
// Set InsecureSkipVerify to skip the default validation
InsecureSkipVerify: true,
...
}
conn, err := tls.Dial("tcp", "example.com:443", conf)
..
...
Email email = new SimpleEmail();
email.setHostName("smtp.servermail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setFrom("user@gmail.com");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("foo@bar.com");
email.send();
...
smtp.mailserver.com:465
연결을 시도할 때 "hackedserver.com
"에 발급된 인증서를 즉시 수락합니다. 그러면 이제 응용 프로그램은 해킹당한 서버에 대한 손상된 SSL 연결에서 민감한 사용자 정보를 누출할 가능성이 있습니다.
...
var options = {
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
requestCert: true,
...
}
https.createServer(options);
...
https.Server
개체가 생성될 때 requestCert
설정이 true
로 지정되지만 rejectUnauthorized
가 설정되지 않습니다. 이는 false
에 대한 기본값입니다. 이렇게 되면 SSL을 통해 클라이언트를 확인하기 위해 서버를 생성해도, 제공된 CA 목록으로 인증서가 인증되지 않은 경우에도 연결이 수락되지 않습니다.
var tls = require('tls');
...
tls.connect({
host: 'https://www.hackersite.com',
port: '443',
...
rejectUnauthorized: false,
...
});
rejectUnauthorized
가 false로 설정되었으므로 인증되지 않은 인증서가 수락되고 확인되지 않은 서버로의 보안 연결도 생성됩니다. 그러면 이제 응용 프로그램은 해킹당한 서버에 대한 손상된 SSL 연결에서 민감한 사용자 정보를 누출할 가능성이 있습니다.NSURLConnectionDelegate
를 구성합니다.
implementation NSURLRequest (IgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
@end
Example 1
의 NSURLRequest
구현을 사용하여 SSL을 통해 보안이 유지되는 서버에 연결하려고 하면 요청된 서버의 인증서가 자체 서명된 인증서인 경우 확인되지 않으므로 경고나 오류가 생성되지 않습니다. 따라서 응용 프로그램이 이제 손상된 SSL 연결을 통해 민감한 사용자 정보를 누출하게 될 수도 있습니다.
...
import ssl
ssl_sock = ssl.wrap_socket(s)
...
require 'openssl'
...
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode=OpenSSL::SSL::VERIFY_NONE
...
NSURLConnectionDelegate
를 구성합니다.
class Delegate: NSObject, NSURLConnectionDelegate {
...
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace?) -> Bool {
return protectionSpace?.authenticationMethod == NSURLAuthenticationMethodServerTrust
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
challenge.sender?.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)
challenge.sender?.continueWithoutCredentialForAuthenticationChallenge(challenge)
}
}
Example 1
의 NSURLConnectionDelegate
구현을 사용하여 SSL을 통해 보안이 유지되는 서버에 연결하려고 하면 요청된 서버의 인증서가 자체 서명된 인증서인 경우 확인되지 않으므로 경고나 오류가 생성되지 않습니다. 따라서 응용 프로그램이 이제 손상된 SSL 연결을 통해 민감한 사용자 정보를 누출하게 될 수도 있습니다.NSURLSession
클래스에서 SSL/TLS 체인 검증은 응용 프로그램의 인증 대리자 메서드에 의해 처리되지만, 사용자(또는 응용 프로그램)를 서버에 인증하기 위해 자격 증명을 제공하는 대신 응용 프로그램은 SSL/TLS 핸드셰이크 도중 서버가 제공하는 자격 증명을 확인한 다음 해당 자격 증명의 수락/거부 여부를 URL 로딩 시스템에 알립니다. 다음 코드는 수신한 챌린지의 proposedCredential
을 세션에 대한 자격 증명으로 다시 전달함으로써 서버 확인을 실제로 우회하는 NSURLSessionDelgate
를 보여 줍니다.
class MySessionDelegate : NSObject, NSURLSessionDelegate {
...
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
...
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, challenge.proposedCredential)
...
}
...
}
...
FINAL(client) = cl_apc_tcp_client_manager=>create(
i_host = ip_adress
i_port = port
i_frame = VALUE apc_tcp_frame(
frame_type =
if_apc_tcp_frame_types=>co_frame_type_terminator
terminator =
terminator )
i_event_handler = event_handler ).
...
client
개체와 원격 서버 간 통신은 암호화되지 않고 인증되지 않은 채널을 통해 전송되므로 손상될 위험이 있습니다.
...
HttpRequest req = new HttpRequest();
req.setEndpoint('http://example.com');
HTTPResponse res = new Http().send(req);
...
HttpResponse
개체인 res
는 암호화 및 인증되지 않는 채널을 통해 제공되기 때문에 침해가 발생할 수 있습니다.
var account = new CloudStorageAccount(storageCredentials, false);
...
String url = 'http://10.0.2.2:11005/v1/key';
Response response = await get(url, headers: headers);
...
response
는 암호화 및 인증되지 않는 채널을 통해 제공되기 때문에 침해가 발생할 수 있습니다.
helloHandler := func(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, world!\n")
}
http.HandleFunc("/hello", helloHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
...
}
instream
은 암호화 및 인증되지 않는 채널을 통해 제공되기 때문에 침해가 발생할 수 있습니다.
var http = require('http');
...
http.request(options, function(res){
...
});
...
http.IncomingMessage
개체인 res
는 암호화 및 인증되지 않는 채널을 통해 제공되기 때문에 침해가 발생할 수 있습니다.
NSString * const USER_URL = @"http://localhost:8080/igoat/user";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:USER_URL]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
...
stream_socket_enable_crypto($fp, false);
...
require 'net/http'
conn = Net::HTTP.new(URI("http://www.website.com/"))
in = conn.get('/index.html')
...
in
은 암호화 및 인증되지 않는 채널을 통해 제공되기 때문에 침해가 발생할 수 있습니다.
val url = Uri.from(scheme = "http", host = "192.0.2.16", port = 80, path = "/")
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = url))
responseFuture
는 암호화 및 인증되지 않는 채널을 통해 제공되기 때문에 침해가 발생할 수 있습니다.
let USER_URL = "http://localhost:8080/igoat/user"
let request : NSMutableURLRequest = NSMutableURLRequest(URL:NSURL(string:USER_URL))
let conn : NSURLConnection = NSURLConnection(request:request, delegate:self)
...
Using(SqlConnection DBconn = new SqlConnection("Data Source=210.10.20.10,1433; Initial Catalog=myDataBase;User ID=myUsername;Password=myPassword;"))
{
...
}
...
...
insecure_config = {
'user': username,
'password': retrievedPassword,
'host': databaseHost,
'port': "3306",
'ssl_disabled': True
}
mysql.connector.connect(**insecure_config)
...
...
using var channel = GrpcChannel.ForAddress("https://grpcserver.com", new GrpcChannelOptions {
Credentials = ChannelCredentials.Insecure
});
...
...
ManagedChannel channel = Grpc.newChannelBuilder("hostname", InsecureChannelCredentials.create()).build();
...
None
으로 설정됩니다. 이처럼 안전하지 않은 채널 자격 증명 설정을 사용하여 주고받는 데이터는 신뢰할 수 없습니다.root_certificates
매개 변수의 값은 None
으로, private_key
매개 변수의 값은 None
으로, certificate_chain
매개 변수의 값은 None
으로 설정됩니다.
...
channel_creds = grpc.ssl_channel_credentials()
...
SmtpClient
는 SMTP 서버와 통신할 때 SSL/TLS를 사용하지 않도록 올바르지 않게 구성되어 있습니다.
string to = "bob@acme.com";
string from = "alice@acme.com";
MailMessage message = new MailMessage(from, to);
message.Subject = "SMTP client.";
message.Body = @"응용 프로그램에서 매우 쉽게 전자 메일을 전송할 수 있습니다.";
SmtpClient client = new SmtpClient("smtp.acme.com");
client.UseDefaultCredentials = true;
client.Send(message);
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.acme.com" />
<property name="port" value="25" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
session = smtplib.SMTP(smtp_server, smtp_port)
session.ehlo()
session.login(username, password)
session.sendmail(frm, to, content)