입력 검증 및 표현 문제는 메타 문자, 대체 인코딩 및 숫자 표현 때문에 발생합니다. 보안 문제는 입력을 신뢰하기 때문에 발생합니다. 문제로는 "Buffer Overflows", "Cross-Site Scripting" 공격, "SQL Injection", 그 외 여러 가지가 있습니다.
...
string password = Request.Form["db_pass"]; //gets POST parameter 'db_pass'
SqlConnection DBconn = new SqlConnection("Data Source = myDataSource; Initial Catalog = db; User ID = myUsername; Password = " + password + ";");
...
db_pass
매개 변수를 제공할 수 있다는 것을 고려하지 않았습니다.
...
password := request.FormValue("db_pass")
db, err := sql.Open("mysql", "user:" + password + "@/dbname")
...
db_pass
매개 변수를 제공할 수 있다는 것을 고려하지 않았습니다.
username = req.field('username')
password = req.field('password')
...
client = MongoClient('mongodb://%s:%s@aMongoDBInstance.com/?ssl=true' % (username, password))
...
password
매개 변수를 제공할 수 있다는 것을 고려하지 않았습니다.
hostname = req.params['host'] #gets POST parameter 'host'
...
conn = PG::Connection.new("connect_timeout=20 dbname=app_development user=#{user} password=#{password} host=#{hostname}")
...
host
매개 변수를 제공할 수 있다는 것을 고려하지 않았습니다.content://my.authority/messages
content://my.authority/messages/123
content://my.authority/messages/deleted
deleted
인 msgld 코드를 제공하여 content://my.authority/messages/deleted
를 호출할 수 있습니다.
// "msgId" is submitted by users
Uri dataUri = Uri.parse(WeatherContentProvider.CONTENT_URI + "/" + msgId);
Cursor wCursor1 = getContentResolver().query(dataUri, null, null, null, null);
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var url:String = String(params["url"]);
var ldr:Loader = new Loader();
var urlReq:URLRequest = new URLRequest(url);
ldr.load(urlReq);
...
message
에서 응답을 검색하여 사용자에게 표시합니다.
client = openai.OpenAI()
res = client.chat.completions.create(...)
message = res.choices[0].message.content
self.writeln(f"<p>{message}<\p>")
text/html
MIME 유형을 지정해야 합니다. 따라서 응답이 이 MIME 유형을 사용하거나 브라우저가 응답을 HTML 또는 스크립트를 실행할 수 있는 다른 문서(예: SVG 이미지(image/svg+xml
), XML 문서(application/xml
) 등)로 렌더링하게 만드는 다른 유형을 사용하는 경우에만 XSS가 가능합니다. application/octet-stream
같은 MIME 유형을 사용하여 응답을 제공할 때 HTML을 렌더링하지 않거나 스크립트를 실행하지 않습니다. 하지만 Internet Explorer와 같은 일부 브라우저는 Content Sniffing
으로 알려진 동작을 수행합니다. 콘텐트 스니핑에서는 제공된 MIME 유형을 무시하고 응답의 콘텐트를 기준으로 올바른 MIME 유형을 추정하려고 시도합니다.text/html
의 MIME 유형은 XSS 취약점으로 이어질 수 있는 MIME 유형 중 하나일 뿐입니다. SVG 이미지(image/svg+xml
), XML 문서(application/xml
) 등과 같은, 스크립트를 실행할 수 있는 다른 문서로 인해 브라우저가 콘텐트 스니핑을 수행하는지 여부와 관계없이 XSS 취약점이 발생할 수 있습니다. <html><body><script>alert(1)</script></body></html>
과 같은 응답은 content-type
헤더가 application/octet-stream
, multipart-mixed
등으로 설정되어 있어도 HTML로 렌더링될 수 있습니다.application/octet-stream
응답에 사용자 데이터를 반영합니다.
@RestController
public class SomeResource {
@RequestMapping(value = "/test", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
public String response5(@RequestParam(value="name") String name){
return name;
}
}
name
매개 변수를 <html><body><script>alert(1)</script></body></html>
로 설정하여 요청을 전송하면 서버는 다음과 같은 응답을 생성합니다.
HTTP/1.1 200 OK
Content-Length: 51
Content-Type: application/octet-stream
Connection: Closed
<html><body><script>alert(1)</script></body></html>
text/html
MIME 유형을 지정해야 합니다. 따라서 응답이 이 MIME 유형을 사용하거나 브라우저가 응답을 HTML 또는 스크립트를 실행할 수 있는 다른 문서(예: SVG 이미지(image/svg+xml
), XML 문서(application/xml
) 등)로 렌더링하게 만드는 다른 유형을 사용하는 경우에만 XSS가 가능합니다. application/json
같은 MIME 유형을 사용하여 응답을 제공할 때 HTML을 렌더링하거나 스크립트를 실행하지 않습니다. 하지만 Internet Explorer와 같은 일부 브라우저는 Content Sniffing
으로 알려진 동작을 수행합니다. 콘텐트 스니핑에서는 제공된 MIME 유형을 무시하고 응답의 콘텐트를 기준으로 올바른 MIME 유형을 추정하려고 시도합니다.그러나 text/html
의 MIME 유형은 XSS 취약점으로 이어질 수 있는 MIME 유형 중 하나일 뿐입니다.image/svg+xml
), XML 문서(application/xml
) 등과 같은, 스크립트를 실행할 수 있는 다른 문서로 인해 브라우저가 콘텐트 스니핑을 수행하는지 여부와 관계없이 XSS 취약점이 발생할 수 있습니다. <html><body><script>alert(1)</script></body></html>
과 같은 응답은 content-type
헤더가 application/json
으로 설정되어 있어도 HTML로 렌더링될 수 있습니다.application/json
응답에 사용자 데이터를 반영합니다.
def mylambda_handler(event, context):
name = event['name']
response = {
"statusCode": 200,
"body": "{'name': name}",
"headers": {
'Content-Type': 'application/json',
}
}
return response
name
매개 변수를 <html><body><script>alert(1)</script></body></html>
로 설정하여 요청을 전송하면 서버는 다음과 같은 응답을 생성합니다.
HTTP/1.1 200 OK
Content-Length: 88
Content-Type: application/json
Connection: Closed
{'name': '<html><body><script>alert(1)</script></body></html>'}
eid
를 읽어 사용자에게 표시합니다.
String queryString = Window.Location.getQueryString();
int pos = queryString.indexOf("eid=")+4;
HTML output = new HTML();
output.setHTML(queryString.substring(pos, queryString.length()));
eid
에 표준 영숫자 텍스트만 있으면 올바로 동작합니다. eid
가 메타 문자나 소스 코드가 포함된 값을 갖는 경우, 웹 브라우저가 HTTP 응답을 표시할 때 코드를 실행합니다.eid
를 읽고 사용자에게 표시합니다.예제 2: 다음의 HTML 형식을 고려해 보십시오.
<SCRIPT>
var pos=document.URL.indexOf("eid=")+4;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<div id="myDiv">
Employee ID: <input type="text" id="eid"><br>
...
<button>Show results</button>
</div>
<div id="resultsDiv">
...
</div>
$(document).ready(function(){
$("#myDiv").on("click", "button", function(){
var eid = $("#eid").val();
$("resultsDiv").append(eid);
...
});
});
eid
인 텍스트 입력에서 직원 ID에 표준 영숫자 텍스트만 있으면 올바로 동작합니다. eid
가 메타 문자나 소스 코드가 포함된 값을 갖는 경우, 웹 브라우저가 HTTP 응답을 표시할 때 코드를 실행합니다.
let element = JSON.parse(getUntrustedInput());
ReactDOM.render(<App>
{element}
</App>);
Example 3
에서 공격자가 getUntrustedInput()
에서 파생된 전체 JSON을 제어할 수 있는 경우 React가 element
를 구성 요소로 렌더링하도록 만들 수 있기 때문에 일반적인 Cross-Site Scripting 공격인 자체 제어 값으로 dangerouslySetInnerHTML
을 이용하여 개체를 전달할 수 있습니다.
<attribute name="href" onInvalid="filterTag">
<regexp-list>
<regexp name="onsiteURL"/>
<regexp name="offsiteURL"/>
</regexp-list>
</attribute>