カプセル化とは、強い境界線を引くことです。Web ブラウザの場合は、自分のモバイル コードが他のモバイル コードに悪用されないようにすることを意味します。サーバー上では、検証されたデータと検証されていないデータ、あるユーザーのデータと別のユーザーのデータ、またはユーザーが見ることを許可されたデータと許可されていないデータの区別などを意味する場合があります。
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()
を宣言しています。ページの URL にアクセスすると、pageAction()
メソッドが実行され、サーバーは 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 攻撃です。アプリケーションには、リクエストの生成元を検証する方法がないために、この攻撃が可能となっています。リクエストはユーザーによって選択された正当なアクションにも、攻撃者が準備した不正なアクションにもなりえます。攻撃者は偽のリクエストを生成する Web ページを見ることができません。そのため、この攻撃方法は、アプリケーションの状態を変更するリクエストにのみ有効です。
<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 攻撃です。アプリケーションには、リクエストの生成元を検証する方法がないために、この攻撃が可能となっています。リクエストはユーザによって選択された正当なアクションにも、攻撃者が準備した不正なアクションにもなりえます。攻撃者は偽のリクエストを生成する Web ページを見ることができません。そのため、この攻撃方法は、アプリケーションの状態を変更するリクエストにのみ有効です。
<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 攻撃です。アプリケーションには、リクエストの生成元を検証する方法がないために、この攻撃が可能となっています。リクエストはユーザによって選択された正当なアクションにも、攻撃者が準備した不正なアクションにもなりえます。攻撃者は偽のリクエストを生成する Web ページを見ることができません。そのため、この攻撃方法は、アプリケーションの状態を変更するリクエストにのみ有効です。buyItem
コントローラー メソッドの CSRF 保護を無効にします。
+ nocsrf
POST /buyItem controllers.ShopController.buyItem
shop.com
のアクティブ セッション実行時に、ユーザーは意図せずに悪意あるページに誘導され、気づかないうちに攻撃者にアイテムを購入してしまいます。 これが CSRF 攻撃です。 アプリケーションには、リクエストの生成元を検証する方法がないために、この攻撃が可能となっています。 リクエストはユーザーによって選択された正当なアクションにも、攻撃者が準備した不正なアクションにもなりえます。 攻撃者は偽のリクエストを生成する Web ページを見ることができません。そのため、この攻撃方法は、アプリケーションの状態を変更するリクエストにのみ有効です。
<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 攻撃です。アプリケーションには、リクエストの生成元を検証する方法がないために、この攻撃が可能となっています。リクエストはユーザによって選択された正当なアクションにも、攻撃者が準備した不正なアクションにもなりえます。攻撃者は偽のリクエストを生成する Web ページを見ることができません。そのため、この攻撃方法は、アプリケーションの状態を変更するリクエストにのみ有効です。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 によってローカルにロードされると、同一生成元ポリシーによって、このファイル内のスクリプトは同じ生成元から生成された他のファイルにアクセスできるようになるため、攻撃者は機密情報を含むすべてのローカル ファイルにアクセスできるようになる可能性があります。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 によってローカルにロードされると、同一生成元ポリシーによって、このファイル内のスクリプトは同じ生成元から生成された他のファイルにアクセスできるようになるため、攻撃者は機密情報を含むすべてのローカル ファイルにアクセスできるようになる可能性があります。crossdomain.xml
設定ファイルの該当する設定によりこのポリシーを変更することを開発者に許可しています。しかし、この設定を変更する場合には、注意が必要です。クロスドメインポリシーが過度に許容的であると、悪意のあるアプリケーションが不正な方法で攻撃対象のアプリケーションとやりとりし、偽装、データの盗み出し、リレーなどの攻撃が実行されるおそれがあるためです。
flash.system.Security.allowDomain("*");
*
を allowDomain()
への引数として使用すると、アプリケーションのデータが、任意のドメインにある他の SWF アプリケーションにアクセスできることになります。