Assert()
を特定の権限で使用する場合、現在の制御フローで権限が指定されていることになります。次にこれによって .NET Framework で必要な権限が満たされている限り追加の権限チェックは停止されます。つまり、Assert()
へのコールを行うコードをコールするコードに必要な権限がない場合があるということです。Assert()
の使用は場合によっては有用ですが、これによって悪意のあるユーザーが権限を持たないリソースを制御できるようになる場合は脆弱性となる可能性があります。
IPAddress hostIPAddress = IPAddress.Parse(RemoteIpAddress);
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
if (hostInfo.HostName.EndsWith("trustme.com")) {
trusted = true;
}
getlogin()
関数を偽装するのは簡単です。このため、関数によって戻された名前を信頼しないようにします。getlogin()
関数は、ターミナルで現在ログオン中のユーザー名を含む文字列を戻しますが、攻撃者は getlogin()
を操作し、そのマシンにログオンした任意のユーザー名を戻すことができます。このため、セキュリティに関する決定を行う際に、getlogin()
関数によって戻された名前を信頼しないようにします。getlogin()
の結果を信頼し、信頼できるユーザーかどうかを判断しています。しかし、これは全く当てになりません。
pwd = getpwnam(getlogin());
if (isTrustedGroup(pwd->pw_gid)) {
allow();
} else {
deny();
}
String ip = request.getRemoteAddr();
InetAddress addr = InetAddress.getByName(ip);
if (addr.getCanonicalHostName().endsWith("trustme.com")) {
trusted = true;
}
Boolean.getBoolean()
は、しばしば Boolean.valueOf()
または Boolean.parseBoolean()
のメソッド呼び出しと混同されます。Boolean.getBoolean()
を呼び出す際は、指定した文字列引数で表現されるブール値が戻されるものと誤解されて使用されています。しかし、Javadoc で説明されているように、Boolean.getBoolean(String)
メソッドは「引数で指定されたシステム プロパティが存在し、しかもそれが文字列 'true' に等しい場合にのみ、true を返す」のです。Boolean.valueOf(String)
または Boolean.parseBoolean(String)
の呼び出しです。Boolean.getBoolean(String)
では String プリミティブを解釈しないため、"FALSE" がプリントされます。解釈されるのはシステムプロパティのみです。
...
String isValid = "true";
if ( Boolean.getBoolean(isValid) ) {
System.out.println("TRUE");
}
else {
System.out.println("FALSE");
}
...
Decoder
および Encoding
クラスの GetChars
メソッドと Encoder
および Encoding
クラスの GetBytes
メソッドは、char および byte 配列に対して内部的にポインタ算術を実行し、文字の範囲をバイトの範囲に (およびその逆に) 変換します。
out.println("x = " + encoder.encodeForJavaScript(input) + ";");
...
unichar ellipsis = 0x2026;
NSString *myString = [NSString stringWithFormat:@"My Test String%C", ellipsis];
NSData *asciiData = [myString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *asciiString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding];
NSLog(@"Original: %@ (length %d)", myString, [myString length]);
NSLog(@"Best-fit-mapped: %@ (length %d)", asciiString, [asciiString length]);
// output:
// Original: My Test String... (length 15)
// Best-fit-mapped: My Test String... (length 17)
...
...
let ellipsis = 0x2026;
let myString = NSString(format:"My Test String %C", ellipsis)
let asciiData = myString.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion:true)
let asciiString = NSString(data:asciiData!, encoding:NSASCIIStringEncoding)
NSLog("Original: %@ (length %d)", myString, myString.length)
NSLog("Best-fit-mapped: %@ (length %d)", asciiString!, asciiString!.length)
// output:
// Original: My Test String ... (length 16)
// Best-fit-mapped: My Test String ... (length 18)
...
_alloca()
関数で、スタックオーバーフロー例外が発生し、その結果プログラムがクラッシュする可能性があります。_alloca()
関数によってスタックにメモリの割り当てが行われます。割り当てリクエストが使用可能なスタック容量を超過した場合、_alloca()
で例外が発生します。例外がキャッチされない場合、プログラムは異常終了し、Denial of Service 攻撃が可能になる可能性があります。_alloca()
の使用は推奨されていません。代わりに、安全性の高い_alloca_s()
を使用するようにします。MAX_PATH
バイト数の長さを持つバッファが必要ですが、各関数については関連資料で確認してください。バッファサイズが処理結果を格納するのに十分でなかった場合には、Buffer Overflow が発生します。
char *createOutputDirectory(char *name) {
char outputDirectoryName[128];
if (getCurrentDirectory(128, outputDirectoryName) == 0) {
return null;
}
if (!PathAppend(outputDirectoryName, "output")) {
return null;
}
if (!PathAppend(outputDirectoryName, name)) {
return null;
}
if (SHCreateDirectoryEx(NULL, outputDirectoryName, NULL)
!= ERROR_SUCCESS) {
return null;
}
return StrDup(outputDirectoryName);
}
output\<name>
」という名前のディレクトリが作成され、ヒープに割り当てたディレクトリ名のコピーを戻しています。この関数は、現在のディレクトリおよび名前パラメーターのほとんどの値で正しく機能します。ただし、name
パラメーターが極端に長いと、PathAppend()
への 2 度目のコールで MAX_PATH
バイト数より小さなバッファである outputDirectoryName
のオーバーフローを引き起こす可能性があります。umask()
に対する引数で指定されるマスクは、よく chmod()
の引数と混同されます。umask()
の man ページは、次のような間違った記述で始まります。chmod()
でユーザーが特定のファイルでアクセス許可を有効にするビットを設定する使用方法と呼応していますが、実際には umask()
の動作は全く正反対です。 umask()
はファイル作成モードを ~mask & 0777
に設定します。umask()
の man ページでは、続いて以下のように正しい umask()
の使用法について述べています。open()
で使用され、新規作成ファイルに対し初期ファイル権限を設定します。 具体的には、open(2)
のモード引数から umask に設定されているビットが引かれます (たとえば一般的な umask のデフォルト値は 022 ですが、モードが 0666 と指定されていると、新規ファイルは 0666 & ~022 = 0644 = rw-r--r-- のアクセス許可で作成されます)。」
...
struct stat output;
int ret = stat(aFilePath, &output);
// error handling omitted for this example
struct timespec accessTime = output.st_atime;
...
umask()
に対する引数で指定されるマスクは、よく chmod()
の引数と混同されます。umask()
の man ページは、次のような間違った記述で始まります。chmod()
でユーザーが特定のファイルでアクセス許可を有効にするビットを設定する使用方法と呼応していますが、実際には umask()
の動作は全く正反対です。umask()
はファイル作成モードを ~mask & 0777
にセットします。umask()
の man ページでは、続いて以下のように正しい umask()
の使用法について述べています。transactionId
を書き込んでいます。
...
//get the documents directory:
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
//make a file name to write the data to using the documents directory:
let fileName = NSString(format:"%@/tmp_activeTrans.txt", documentsPath)
// write data to the file
let transactionId = "TransactionId=12341234"
transactionId.writeToFile(fileName, atomically:true)
...
posted
オブジェクトに割り当てます。FileUpload
は System.Web.UI.HtmlControls.HtmlInputFile
のタイプです。
HttpPostedFile posted = FileUpload.PostedFile;
@Controller
public class MyFormController {
...
@RequestMapping("/test")
public String uploadFile (org.springframework.web.multipart.MultipartFile file) {
...
} ...
}
<?php
$udir = 'upload/'; // Relative path under Web root
$ufile = $udir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $ufile)) {
echo "Valid upload received\n";
} else {
echo "Invalid upload rejected\n";
} ?>
from django.core.files.storage import default_storage
from django.core.files.base import File
...
def handle_upload(request):
files = request.FILES
for f in files.values():
path = default_storage.save('upload/', File(f))
...
file
タイプの <input>
タグは、そのプログラムでファイルのアップロードが許可されていることを示します。
<input type="file">
myModule.config(function($interpolateProvider){
$interpolateProvider.startSymbol("[[");
$interpolateProvider.endSymbol("]]");
});
root
権限を使って実行するプログラムが原因で無数のセキュリティ被害が発生しています。多種のセキュリティ問題に対して、権限を必要とするプログラムを注意深く調べることは非常に大切です。しかし、それ以上に重要なのは、見逃された脆弱性によって発生する被害の拡大を防ぐために、権限を持ったプログラムを権限のない状態になるべく早く戻すことです。root
以外のユーザー間で移動する場合にとりわけ顕著に現れます。 root
としてプロセスを実行している場合は、シグナルハンドラまたはサブプロセスはルート権限で動作します。攻撃者はこの昇格された権限を利用して、さらに大きな打撃を与える可能性があります。root
権限で実行されるプログラムは、数え切れないほどの Unix セキュリティ災害を引き起こしてきました。権限が必要なプログラムにあらゆる種類のセキュリティ上の問題がないか慎重に検討することは必要ですが、見落とされた脆弱性が引き起こす被害を最小限に抑えるために、権限が必要なプログラムの権限をできるだけ早く降格することも同様に重要です。root
ユーザーから別のユーザーに移行する場合に特に顕著になります。root
として実行されている場合、シグナル ハンドラーやサブプロセスは root 権限で動作します。攻撃者は、これらの昇格された特権を利用して、さらなる損害を与えることができる可能性があります。root
権限を使って実行するプログラムが原因で無数のセキュリティ被害が発生しています。 多種のセキュリティ問題に対して、権限を必要とするプログラムを注意深く調べることは非常に大切です。しかし、それ以上に重要なのは、見逃された脆弱性によって発生する被害の拡大を防ぐために、権限を持ったプログラムを権限のない状態になるべく早く戻すことです。root
以外のユーザー間で移動する場合にとりわけ顕著に現れます。root
としてプロセスを実行している場合は、シグナルハンドラまたはサブプロセスはルート権限で動作します。攻撃者はこの昇格された権限を利用して、さらに大きな打撃を与える可能性があります。root
権限を使って実行するプログラムが原因で無数のセキュリティ被害が発生しています。多種のセキュリティ問題に対して、権限を必要とするプログラムを注意深く調べることは非常に大切です。しかし、それ以上に重要なのは、見逃された脆弱性によって発生する被害の拡大を防ぐために、権限を持ったプログラムを権限のない状態になるべく早く戻すことです。root
以外のユーザー間で移動する場合にとりわけ顕著に現れます。root
としてプロセスを実行している場合は、シグナルハンドラまたはサブプロセスはルート権限で動作します。攻撃者はこの昇格された権限を利用して、さらに大きな打撃を与える可能性があります。...
Device.OpenUri("sms:+12345678910");
...
...
[[CTMessageCenter sharedMessageCenter] sendSMSWithText:@"Hello world!" serviceCenter:nil toAddress:@"+12345678910"];
...
// or
...
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:+12345678910"]];
...
// or
...
MFMessageComposeViewController *messageComposerVC = [[MFMessageComposeViewController alloc] init];
[messageComposerVC setMessageComposeDelegate:self];
[messageComposerVC setBody:@"Hello World!"];
[messageComposerVC setRecipients:[NSArray arrayWithObject:@"+12345678910"]];
[self presentViewController:messageComposerVC animated:YES completion:nil];
...
...
UIApplication.sharedApplication().openURL(NSURL(string: "sms:+12345678910"))
...
...
let messageComposeVC = MFMessageComposeViewController()
messageComposeVC.messageComposeDelegate = self
messageComposeVC.body = "Hello World!"
messageComposeVC.recipients = ["+12345678910"]
presentViewController(messageComposeVC, animated: true, completion: nil)
...
MultiByteToWideChar()
、WideCharToMultiByte()
、UnicodeToBytes()
、および BytesToUnicode()
といった関数で任意のマルチバイト文字列 (通常ANSI) と Unicode 文字列 (ワイド文字) を変換します。こうした関数へ渡すサイズ引数は、1 つの関数ではバイト数、他方では文字数と異なる単位で指定されるため、エラーが発生しやすくなります。マルチバイト文字列では各文字のバイト数が異なるため、文字列の長さはバイトの合計サイズを使うと簡単に指定できます。一方 Unicode では、文字は常に固定サイズであるため、文字列の長さは通常、含まれる文字数で決まります。サイズ引数を間違った単位で指定すると、Buffer Overflow の原因となる可能性があります。
void getUserInfo(char *username, struct _USER_INFO_2 info){
WCHAR unicodeUser[UNLEN+1];
MultiByteToWideChar(CP_ACP, 0, username, -1,
unicodeUser, sizeof(unicodeUser));
NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
}
unicodeUser
のサイズを、文字数でなく、誤ってバイト単位で渡しています。このため、MultiByteToWideChar()
へのコールにより最大で (UNLEN+1)*sizeof(WCHAR
) 個のワイド文字、または (UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
バイトを unicodeUser
配列に書き込むことが可能ですが、この配列には (UNLEN+1)*sizeof(WCHAR)
バイトしか割り当てられていません。username
文字列に含まれる文字数が UNLEN
字を超えている場合、MultiByteToWideChar()
のコールにより、バッファ unicodeUser
はオーバーフローします。sun.misc.Unsafe
の機能を使用します。このクラスのすべての機能は本質的に安全に使用できず、リフレクション経由でのみアクセスできます。sun.misc.Unsafe
クラスは、安全でない低レベルの操作を実行するためのものであり、開発者による使用を目的としていません。Unsafe
クラスは信頼できるコードによってのみ取得でき、通常はリフレクションを通じて取得されます。これは、このクラスがシステムの破損やヒープ メモリの手動割り当てに使用される可能性があり、適切に処理しないとシステムに悪影響を及ぼす可能性があるためです。sun.misc.Unsafe
に関するすべての機能を慎重にレビューし、問題がないことをテストすることが不可欠です。Value Stack
のコンテキストで EL 式を評価できます。 Value Stack
に対する未検証の式の評価を許可することにより、攻撃者がシステム変数にアクセスして改変したり、任意のコードを実行したりできるようになります。
OgnlContext ctx = new OgnlContext();
String expression = request.getParameter("input");
Object expr = Ognl.parseExpression(expression);
Object value = Ognl.getValue(expr, ctx, root);
System.out.println("Value: " + value);
(#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc.exe"))
%{expr}
) を使用します。最初の評価の結果を掌握している攻撃者が、2 回目の OGNL 評価で評価される式を制御し、任意の OGNL 式を挿入できるようになる可能性があります。redirectAction
の結果はそのパラメーターを 2 回評価することが知られています。この場合、攻撃者が redirect
リクエスト パラメーターを指定することで、actionName
パラメータの強制 OGNL 式の結果を制御する可能性があります。
...
<action name="index" class="com.acme.MyAction">
<result type="redirectAction">
<param name="actionName">${#parameters['redirect']}</param>
<param name="namespace">/foo</param>
</result>
</action>
...
%{#parameters['redirect']}
式を評価してユーザー制御の文字列を返しますが、これが OGNL 式として評価されることで、攻撃者が任意の OGNL 式を評価できるようになります。execute()
以外のメソッドを公開できるようにする "動的メソッド呼び出し" と呼ばれる機能を導入しました。!
(感嘆符) 文字または method:
プレフィックスをアクション URL で使用すると、"動的メソッド呼び出し" が有効な場合、アクションで任意のパブリック メソッドを呼び出すことができます。Struts 2 バージョン 2.3.20
では、以前はリフレクションに基づいていた代替メソッドを呼び出すメカニズムが、代わりに OGNL を使用するように置き換えられ、攻撃者が代替メソッド名の代わりに悪意のある OGNL 式を提供できるようになりました。debug
リクエスト パラメーターを使用することでトリガーできます。console
: を使用すると、OGNL 評価コンソールがポップアップ表示され、開発者はサーバー上の任意の OGNL 式を評価できます。command
: を使用すると、開発者がリクエスト パラメーター expression
を使用して、評価する任意の OGNL 式を送信できます。xml
を使用すると、パラメーター、コンテキスト、セッションおよびバリュースタックが XML ドキュメントとしてダンプされます。browser
を使用すると、パラメーター、コンテキスト、セッションおよびバリュースタックが、閲覧可能な HTML ドキュメントにダンプされます。dest
リクエストパラメーターからパースされた URL を開くように命令しています。
...
DATA: str_dest TYPE c.
str_dest = request->get_form_field( 'dest' ).
response->redirect( str_dest ).
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエストパラメーターから読み取られた URL を開くように命令しています。
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var strDest:String = String(params["dest"]);
host.updateLocation(strDest);
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエスト パラメーターからの URL を含む PageReference
オブジェクトを返します。
public PageReference pageAction() {
...
PageReference ref = ApexPages.currentPage();
Map<String,String> params = ref.getParameters();
return new PageReference(params.get('dest'));
}
Example 1
のコードによってブラウザーは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエストパラメーターからパースされた URL を開くように命令しています。
String redirect = Request["dest"];
Response.Redirect(redirect);
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエスト パラメーターからパースされた URL を開くよう指示しています。
...
final server = await HttpServer.bind(host, port);
await for (HttpRequest request in server) {
final response = request.response;
final headers = request.headers;
final strDest = headers.value('strDest');
response.headers.contentType = ContentType.text;
response.redirect(Uri.parse(strDest!));
await response.close();
}
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエスト パラメーターからパースされた URL を開くよう指示しています。
...
strDest := r.Form.Get("dest")
http.Redirect(w, r, strDest, http.StatusSeeOther)
...
Example 1
のコードによって、ブラウザーは「http://www.wilyhacker.com」にリダイレクトされます。dest
リクエスト パラメーターからパースされた URL を開くよう指示しています。
<end-state id="redirectView" view="externalRedirect:#{requestParameters.dest}" />
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエスト パラメーターから読み取られた URL を開くように命令しています。
...
strDest = form.dest.value;
window.open(strDest,"myresults");
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエストパラメーターからパースされた URL を開くように命令しています。
<%
...
$strDest = $_GET["dest"];
header("Location: " . $strDest);
...
%>
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエストパラメーターからパースされた URL を開くように命令しています。
...
-- Assume QUERY_STRING looks like dest=http://www.wilyhacker.com
dest := SUBSTR(OWA_UTIL.get_cgi_env('QUERY_STRING'), 6);
OWA_UTIL.redirect_url('dest');
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエストパラメーターからパースされた URL を開くように命令しています。
...
strDest = request.field("dest")
redirect(strDest)
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエスト パラメーターからパースされた URL を開くように命令しています。
...
str_dest = req.params['dest']
...
res = Rack::Response.new
...
res.redirect("http://#{dest}")
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。dest
リクエスト パラメーターからパースされた URL を開くように命令しています。
def myAction = Action { implicit request =>
...
request.getQueryString("dest") match {
case Some(location) => Redirect(location)
case None => Ok("No url found!")
}
...
}
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。http://
スキームを使用して元の URL をポイントするように requestToLoad
を設定し、さらにこのリクエストを WKWebView 内でロードします。
...
let requestToLoad : String
...
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
...
if let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false) {
if let queryItems = urlComponents.queryItems as? [NSURLQueryItem]{
for queryItem in queryItems {
if queryItem.name == "dest" {
if let value = queryItem.value {
request = NSURLRequest(URL:NSURL(string:value))
requestToLoad = request
break
}
}
}
}
if requestToLoad == nil {
urlComponents.scheme = "http"
requestToLoad = NSURLRequest(URL:urlComponents.URL)
}
}
...
}
...
...
let webView : WKWebView
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
webView.loadRequest(appDelegate.requestToLoad)
...
Example 1
のコードによって WKWebView で "http://www.wilyhacker.com" がリクエストおよびロードされます。dest
リクエストパラメータからパースされた URL を開くように命令しています。
...
strDest = Request.Form('dest')
HyperLink.NavigateTo strDest
...
Example 1
のコードによってブラウザは "http://www.wilyhacker.com" にリダイレクトされることになります。security
の要件とターゲット servers
の定義は、常にそれぞれのグローバル設定をオーバーライドします。 security
の要件とターゲット servers
の定義は、常にそれぞれのグローバル設定をオーバーライドします。