API は、呼び出し元と呼び出し先の間のコントラクトです。最も一般的な API の不正使用の形態は、呼び出し元がこのコントラクトの終わりを守らないことによって発生します。たとえば、プログラムが chroot() を呼び出した後に chdir() を呼び出すのに失敗すると、アクティブなルート ディレクトリを安全に変更する方法を指定したコントラクトに違反することになります。ライブラリの悪用のもう 1 つの良い例は、呼び出し先が信頼できる DNS 情報を呼び出し元に返すことを期待することです。この場合、呼び出し元は、呼び出し先の API の動作 (戻り値が認証目的に使用できること) についてある種の仮定をすることで、呼び出し先の API を悪用します。また、相手側から、呼び出し元と呼び出し先のコントラクトを違反することもできます。例えば、コーダーが SecureRandom をサブクラス化し、ランダムではない値を返した場合、コントラクトに違反することになります。
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("]]");
});