캡슐화는 강력한 경계를 그리는 것입니다. 웹 브라우저에서는 사용자의 모바일 코드가 다른 모바일 코드에 의해 오용되지 않도록 하는 것을 의미합니다. 서버에서는 검증된 데이터와 검증되지 않은 데이터, 한 사용자의 데이터와 다른 사용자의 데이터, 데이터 사용자가 볼 수 있는 데이터와 볼 수 없는 데이터 간의 차별화를 의미할 수 있습니다.
X-Frame-Options
헤더를 통해 프레이밍 정책을 지정하지 못하는 경우X-Frame-Options
헤더를 통해 프레이밍 정책을 지정하지 못하는 경우localStorage
및 sessionStorage
사이의 값을 이동하면 모르는 사이에 민감한 정보가 노출될 수 있습니다.localStorage
및 sessionStorage
맵을 제공합니다. sessionStorage
맵은 페이지를 호출하기 위한 저장소를 제공하며 페이지 인스턴스 및 즉각적인 브라우저 세션 동안에만 지속됩니다. 그러나, localStorage
맵은 여러 페이지 인스턴스 및 브라우저 인스턴스에 대해 액세스할 수 있는 저장소를 제공합니다. 이 기능을 통해 응용 프로그램은 여러 브라우저 탭 또는 창에서 동일한 정보를 유지하고 활용할 수 있습니다.sessionStorage
범위에서 localStorage
또는 그 반대로 민감한 정보를 이동시키지 않도록 주의해야 합니다.sessionStorage
개체에 저장됩니다. 그러나 개발자도 localStorage
개체 내에 정보를 저장합니다.
...
try {
sessionStorage.setItem("userCCV", currentCCV);
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert('Quota exceeded.');
}
}
...
...
var retrieveObject = sessionStorage.getItem("userCCV");
try {
localStorage.setItem("userCCV",retrieveObject);
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert('Quota exceeded.');
}
...
var userCCV = localStorage.getItem("userCCV");
...
}
...
localStorage
개체로 되돌려 놓으면, 이제 CCV 정보는 다른 브라우저 탭에서 이용할 수 있으며 브라우저의 새 호출 시에도 이용 가능합니다. 그러면 의도한 워크플로우에 대한 응용 프로그램 로직은 무시됩니다.MyAccountActions
및 페이지 작업 메서드 pageAction()
을 선언합니다. pageAction()
메서드는 페이지 URL 방문 시에 실행되며 서버는 CSRF 토큰 유무를 확인하지 않습니다.
<apex:page controller="MyAccountActions" action="{!pageAction}">
...
</apex:page>
public class MyAccountActions {
...
public void pageAction() {
Map<String,String> reqParams = ApexPages.currentPage().getParameters();
if (params.containsKey('id')) {
Id id = reqParams.get('id');
Account acct = [SELECT Id,Name FROM Account WHERE Id = :id];
delete acct;
}
}
...
}
<img src="http://my-org.my.salesforce.com/apex/mypage?id=YellowSubmarine" height=1 width=1/>
RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, "/new_user");
body = addToPost(body, new_username);
body = addToPost(body, new_passwd);
rb.sendRequest(body, new NewAccountCallback(callback));
RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, "http://www.example.com/new_user");
body = addToPost(body, "attacker";
body = addToPost(body, "haha");
rb.sendRequest(body, new NewAccountCallback(callback));
example.com
의 관리자가 사이트에서 세션을 활성화한 상태에서 악성 페이지를 방문하는 경우 무의식적으로 공격자를 위한 계정을 만들게 됩니다. 이것이 CSRF 공격입니다. 이 공격이 가능한 이유는 응용 프로그램에 해당 요청의 출처를 확인할 방법이 없기 때문입니다. 모든 요청은 사용자가 선택한 적법한 작업이거나 공격자가 설정한 허위 작업일 가능성이 있습니다. 공격자는 허위 요청이 생성하는 웹 페이지를 보지 못하므로 이 공격 기법은 응용 프로그램의 상태를 변경하는 요청의 경우에만 유용합니다.
<http auto-config="true">
...
<csrf disabled="true"/>
</http>
var req = new XMLHttpRequest();
req.open("POST", "/new_user", true);
body = addToPost(body, new_username);
body = addToPost(body, new_passwd);
req.send(body);
var req = new XMLHttpRequest();
req.open("POST", "http://www.example.com/new_user", true);
body = addToPost(body, "attacker");
body = addToPost(body, "haha");
req.send(body);
example.com
의 관리자가 사이트에서 세션을 활성화한 상태에서 악성 페이지를 방문하는 경우 무의식적으로 공격자를 위한 계정을 만들게 됩니다. 이것이 CSRF 공격입니다. 이는 응용 프로그램이 해당 요청의 출처를 확인하는 방법을 가지고 있지 않기 때문입니다. 모든 요청은 사용자가 선택한 적법한 작업이거나 공격자가 설정한 허위 작업일 가능성이 있습니다. 공격자는 허위 요청이 생성하는 웹 페이지를 보지 못하므로 이 공격 기법은 응용 프로그램의 상태를 변경하는 요청의 경우에만 유용합니다.
<form method="POST" action="/new_user" >
Name of new user: <input type="text" name="username">
Password for new user: <input type="password" name="user_passwd">
<input type="submit" name="action" value="Create User">
</form>
<form method="POST" action="http://www.example.com/new_user">
<input type="hidden" name="username" value="hacker">
<input type="hidden" name="user_passwd" value="hacked">
</form>
<script>
document.usr_form.submit();
</script>
example.com
의 관리자가 사이트에서 세션을 활성화한 상태에서 악성 페이지를 방문하는 경우 무의식적으로 공격자를 위한 계정을 만들게 됩니다. 이것이 CSRF 공격입니다. 이는 응용 프로그램이 해당 요청의 출처를 확인하는 방법을 가지고 있지 않기 때문입니다. 모든 요청은 사용자가 선택한 적법한 작업이거나 공격자가 설정한 허위 작업일 가능성이 있습니다. 공격자는 허위 요청이 생성하는 웹 페이지를 보지 못하므로 이 공격 기법은 응용 프로그램의 상태를 변경하는 요청의 경우에만 유용합니다.buyItem
컨트롤러 메서드에 대한 CSRF 보호를 비활성화합니다.
+ nocsrf
POST /buyItem controllers.ShopController.buyItem
shop.com
의 활성 세션에 있는 동안 악성 페이지를 방문하게 되면 의도치 않게 공격자의 물품을 구입하게 됩니다. 이것이 CSRF 공격입니다. 이 공격이 가능한 이유는 응용 프로그램에 해당 요청의 출처를 확인할 방법이 없기 때문입니다. 모든 요청은 사용자가 선택한 적법한 작업이거나 공격자가 설정한 허위 작업일 가능성이 있습니다. 공격자는 허위 요청이 생성하는 웹 페이지를 보지 못하므로 이 공격 기법은 응용 프로그램의 상태를 변경하는 요청의 경우에만 유용합니다.
<form method="POST" action="/new_user" >
Name of new user: <input type="text" name="username">
Password for new user: <input type="password" name="user_passwd">
<input type="submit" name="action" value="Create User">
</form>
<form method="POST" action="http://www.example.com/new_user">
<input type="hidden" name="username" value="hacker">
<input type="hidden" name="user_passwd" value="hacked">
</form>
<script>
document.usr_form.submit();
</script>
example.com
의 관리자가 사이트에서 세션을 활성화한 상태에서 악성 페이지를 방문하는 경우 무의식적으로 공격자를 위한 계정을 만들게 됩니다. 이것이 CSRF 공격입니다. 이는 응용 프로그램이 해당 요청의 출처를 확인하는 방법을 가지고 있지 않기 때문입니다. 모든 요청은 사용자가 선택한 적법한 작업이거나 공격자가 설정한 허위 작업일 가능성이 있습니다. 공격자는 허위 요청이 생성하는 웹 페이지를 보지 못하므로 이 공격 기법은 응용 프로그램의 상태를 변경하는 요청의 경우에만 유용합니다.noopen
으로 설정되는 X-Download-Options
헤더를 비활성화하면 다운로드된 HTML 페이지가 이를 제공하는 사이트의 보안 컨텍스트에서 실행됩니다.
var express = require('express');
var app = express();
var helmet = require('helmet');
app.use(helmet({
ieNoOpen: false
}));
...
Origin
헤더를 확인하지 못하면 모든 악성 사이트가 사용자를 가장하여 사용자 모르게 양방향 WebSocket 연결을 설정할 수 있게 됩니다.Origin
헤더를 확인하지 못하면 모든 악성 사이트가 사용자를 가장하여 사용자 모르게 양방향 WebSocket 연결을 설정할 수 있게 됩니다.exclude
거부 목록을 사용합니다. 이는 관리하기가 어려울 뿐 아니라 오류에도 취약합니다. 개발자가 폼이나 폼을 백업하는 Model
에 새 필드를 추가하는 상황에서 exclude
필터를 업데이트하는 것을 잊어버리는 경우 공격자에게 민감한 필드를 노출할 수도 있습니다. 공격자는 악의적인 데이터를 제외되지 않는 필드로 전송하고 바인딩할 수 있습니다.User
속성을 노출하지만 사용자 id
에 대한 거부 목록을 검사합니다.
from myapp.models import User
...
class UserForm(ModelForm):
class Meta:
model = User
exclude = ['id']
...
User
모델은 새 role
속성으로 업데이트되었지만 연결된 UserForm
은 업데이트되지 않은 경우 폼에서 role
속성이 노출됩니다.
...
myWebView.loadUrl("file:///android_asset/www/index.html");
...
Example 1
에서 Android WebView 렌더러는 “file://”로 시작하는 URL을 사용하여 loadUrl()
로 로드되는 모든 것을 출처가 동일한 것으로 취급합니다.
<script src="http://www.example.com/js/fancyWidget.js"></script>
Example 2
에서는 결과 스크립트를 악의적 작업자가 수정하는 것이 가능한 안전하지 않은 프로토콜이 사용됩니다. 또는 컴퓨터를 공격자의 사이트로 경로 재지정하는 다른 공격이 수행될 수 있습니다.file://
).UIWebView.loadRequest(_:)
메서드를 사용하여 로컬 파일을 로드합니다.
...
NSURL *url = [[NSBundle mainBundle] URLForResource: filename withExtension:extension];
[webView loadRequest:[[NSURLRequest alloc] initWithURL:url]];
...
Example 1
에서, WebView 엔진은 file://
로 시작하는 URL을 사용하여 UIWebView.loadRequest(_:)
를 통해 로드되는 모든 것을 권한 있는 로컬 파일 출처에 있는 것으로 취급합니다.file://
URL을 통해 로컬에 로드된 경우, 동일 출처 정책(Same Origin Policy)은 이 파일의 스크립트가 동일 출처의 다른 파일에 액세스할 수 있도록 허용하므로 공격자가 민감한 정보가 포함된 로컬 파일에 액세스할 수 있습니다.file://
).UIWebView.loadRequest(_:)
메서드를 사용하여 로컬 파일을 로드합니다.
...
let url = Bundle.main.url(forResource: filename, withExtension: extension)
self.webView!.load(URLRequest(url:url!))
...
Example 1
에서, WebView 엔진은 file://
로 시작하는 URL을 사용하여 UIWebView.loadRequest(_:)
를 통해 로드되는 모든 것을 권한 있는 로컬 파일 출처에 있는 것으로 취급합니다.file://
URL을 통해 로컬에 로드된 경우, 동일 출처 정책(Same Origin Policy)은 이 파일의 스크립트가 동일 출처의 다른 파일에 액세스할 수 있도록 허용하므로 공격자가 민감한 정보가 포함된 로컬 파일에 액세스할 수 있습니다.crossdomain.xml
구성 파일의 적절한 설정을 통해 정책을 수정할 수 있습니다. 그러나, 지나치게 허용적인 도메인 간 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 설정 변경 시 주의해야 합니다.
flash.system.Security.allowDomain("*");
*
를 allowDomain()
에 대한 인수로 사용하는 것은 응용 프로그램의 데이터가 임의의 도메인에서 다른 SWF 응용 프로그램으로 접근할 수 있음을 나타냅니다.crossdomain.xml
구성 파일의 적절한 설정을 통해 정책을 수정할 수 있습니다. Flash Player 9,0,124,0부터 Adobe는 Flash Player에서 여러 도메인에 걸쳐 보낼 수 있는 사용자 지정 헤더를 정의하는 기능도 도입했습니다. 그러나 지나치게 허용적인 도메인 간 정책과 함께 적용할 경우, 지나치게 허용적인 사용자 지정 헤더 정책은 선택된 헤더를 악성 응용 프로그램이 대상 응용 프로그램으로 전송할 수 있어, 수신한 헤더를 처리하지 못하는 응용 프로그램 실행 시 다양한 공격으로 이어지거나 오류가 발생할 수 있기 때문에 이러한 설정 정의 시 주의해야 합니다.
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
*
를 headers
속성 값으로 사용하면 모든 헤더가 여러 도메인에 걸쳐 전송됨을 나타냅니다.crossdomain.xml
구성 파일의 적절한 설정을 통해 정책을 수정할 수 있습니다. 그러나, 지나치게 허용적인 도메인 간 정책을 사용하면 악성 응용 프로그램이 부적절한 방법으로 피해자 응용 프로그램과 통신하여 스푸핑, 데이터 도난, 릴레이 및 기타 공격으로 이어질 수 있기 때문에 설정에 영향을 미칠 수 있는 사람을 결정할 때 주의해야 합니다. 정책 제한 무시 취약점은 다음과 같은 경우 발생합니다.예제 2: 다음 코드는 로드한 SWF 파일에 대한 매개변수 중 하나의 값을 사용하여 신뢰할 수 있는 도메인 목록을 정의합니다.
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var url:String = String(params["url"]);
flash.system.Security.loadPolicyFile(url);
...
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var domain:String = String(params["domain"]);
flash.system.Security.allowDomain(domain);
...
crossdomain.xml
구성 파일의 적절한 설정을 통해 이 제한을 수정할 수 있습니다. 그러나 HTTP로 로드한 SWF 응용 프로그램은 MITM(Man-In-The-Middle) 공격을 받을 수 있으므로 이러한 설정 정의 시 주의해야 하며, 따라서 신뢰하지 말아야 합니다.allowInsecureDomain()
을 호출하여 HTTP로 로드된 SWF 응용 프로그램이 HTTPS로 로드된 SWF 응용 프로그램의 데이터에 접근하는 것을 막는 제한을 끕니다.
flash.system.Security.allowInsecureDomain("*");
app.use('/graphql', graphqlHTTP({
schema
}));
app.add_url_rule('/graphql', view_func=GraphQLView.as_view(
'graphql',
schema = schema,
graphiql = True
))
services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>();
app.use('/graphql', graphqlHTTP({
schema
}));
app.add_url_rule('/graphql', view_func=GraphQLView.as_view(
'graphql',
schema = schema
))
script
태그를 고려하십시오.
<script src="http://www.example.com/js/fancyWidget.js"></script>
www.example.com
이 아닌 다른 웹 사이트에 나타나는 경우, 이 사이트의 정확한 비 악성 코드 사용 여부는 www.example.com
에 따라 달라지게 됩니다. 공격자가 www.example.com
을 손상시킨 경우, fancyWidget.js
의 내용을 변경하여 사이트 보안을 침해할 수 있습니다. 예를 들어 fancyWidget.js
에 코드를 추가하여 사용자의 기밀 데이터를 훔칠 수 있습니다.
HtmlInputHidden hidden = new HtmlInputHidden();
Hidden hidden = new Hidden(element);
hidden
형식의 <input>
태그는 숨겨진 필드를 사용하고 있음을 나타냅니다.
<input type="hidden">
...
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
...
'mydb'
로 추측할 수 있는 사람은 누구나 데이터베이스에 액세스할 수 있습니다.script-src
, img-src
, object-src
, style_src
, font-src
, media-src
, frame-src
, connect-src
.*
를 사용할 수도 있습니다. 지정자를 반드시 사용해야 하는 것은 아닙니다. 브라우저는 목록에 나열되지 않은 지정자에 대해 모든 소스를 허용하기도 하고 선택적 default-src
지정자에서 값을 파생하기도 합니다. 또한, 이 헤더의 사양은 시간이 지남에 따라 발전해 왔습니다. Firefox(버전 23까지)와 IE(버전 10까지)에서는 X-Content-Security-Policy
로 구현되어 있었으며 Chrome(버전 25까지)에서는 X-Webkit-CSP
로 구현되어 있었습니다. 하지만 이제는 새 표준 이름인 Content Security Policy
를 사용하기 위해 두 이름 모두 더 이상 사용되지 않습니다. 지정자의 수, 더 이상 사용되지 않는 2개의 대체 이름, 그리고 단일 헤더에서 여러 번 나타나는 동일한 헤더와 반복되는 지정자가 처리되는 방식을 감안하면 개발자가 이 헤더를 잘못 구성할 확률이 높습니다.unsafe-inline
또는 unsafe-eval
이 포함된 지정자는 CSP를 사용하는 목적을 무효화합니다.script-src
지정자가 설정되어 있지만 nonce
스크립트는 구성되어 있지 않습니다.frame-src
가 설정되어 있지만 sandbox
는 구성되어 있지 않습니다.django-csp
구성에서는 안전하지 않은 unsafe-inline
및 unsafe-eval
지정자를 사용하여 인라인 스크립트 및 코드 평가를 허용합니다.
...
MIDDLEWARE = (
...
'csp.middleware.CSPMiddleware',
...
)
...
CSP_DEFAULT_SRC = ("'self'", "'unsafe-inline'", "'unsafe-eval'", 'cdn.example.net')
...
X-Frame-Options
헤더가 포함됩니다. 이 헤더를 사용하지 않거나 설정하지 않으면 cross-frame 관련 취약점이 발생할 수 있습니다.X-Frame-Options
헤더를 사용하지 않도록 Spring Security로 보호된 응용 프로그램을 구성합니다.
<http auto-config="true">
...
<headers>
...
<frame-options disabled="true"/>
</headers>
</http>