API は、呼び出し元と呼び出し先の間のコントラクトです。最も一般的な API の不正使用の形態は、呼び出し元がこのコントラクトの終わりを守らないことによって発生します。たとえば、プログラムが chroot() を呼び出した後に chdir() を呼び出すのに失敗すると、アクティブなルート ディレクトリを安全に変更する方法を指定したコントラクトに違反することになります。ライブラリの悪用のもう 1 つの良い例は、呼び出し先が信頼できる DNS 情報を呼び出し元に返すことを期待することです。この場合、呼び出し元は、呼び出し先の API の動作 (戻り値が認証目的に使用できること) についてある種の仮定をすることで、呼び出し先の API を悪用します。また、相手側から、呼び出し元と呼び出し先のコントラクトを違反することもできます。例えば、コーダーが SecureRandom をサブクラス化し、ランダムではない値を返した場合、コントラクトに違反することになります。
_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
に関するすべての機能を慎重にレビューし、問題がないことをテストすることが不可欠です。
String password=request.getParameter("password");
...
DefaultUser user = (DefaultUser) ESAPI.authenticator().createUser(username, password, password);
finalize()
メソッドは、オブジェクトがガベージコレクトされた後に JVM にコールされるようにします。finalize()
メソッドを finalizer 外部からコールすることができます。通常は、これは良い考えではありません。たとえば、finalize()
をコールすることは、finalize()
が 2 回以上コールされることを明示的に意味しています。一回目は明示的なコールで、最後はオブジェクトがガベージコレクトされた後に行われるコールです。finalize()
を明示的にコールします。
// time to clean up
widget.finalize();
dangerouslySetInnerHTML
属性は、不必要にコードから HTML を設定します。dangerouslySetInnerHTML
属性は、ブラウザー DOM での innerHTML の使用に代わるものです。API 名は、これを使用することによる潜在的な危険性を伝えるために変更されています。一般に、コードから HTML を設定することは危険です。ユーザーを誤って Cross-Site Scripting (XSS) 攻撃にさらす可能性が高いためです。dangerouslySetInnerHTML
属性に設定します。
function MyComponent(data) {
return (
<div
dangerouslySetInnerHTML={{__html: data.innerHTML}}
/>
);
}
AUTHID CURRENT_USER
パッケージでは、現在のユーザースキーマに対して識別子が最初に解決されます。その結果、識別子がどのスキーマに属しているのかをコードの定義が明示していない場合、予期せぬ動作が引き起こされる可能性があります。SYS.PERMISSIONS
に対してのみ読み取りアクセスが許可されるようになり、定義済みの権限を変更できません。
CREATE or REPLACE FUNCTION check_permissions(
p_name IN VARCHAR2, p_action IN VARCHAR2)
RETURN BOOLEAN
AUTHID CURRENT_USER
IS
r_count NUMBER;
perm BOOLEAN := FALSE;
BEGIN
SELECT count(*) INTO r_count FROM PERMISSIONS
WHERE name = p_name AND action = p_action;
IF r_count > 0 THEN
perm := TRUE;
END IF;
RETURN perm;
END check_permissions
check_permissions
関数をコールするユーザーがスキーマで PERMISSIONS
テーブルを定義する場合、データベースが識別子を解決して、ローカルテーブルを参照します。ユーザーは新しいテーブルに対する書き込み権限を付与されるため、データベースを変更することによって本来付与されないはずの権限を取得できるようになります。org.apache.struts2.interceptor.ApplicationtAware
、org.apache.struts2.interceptor.SessionAware
、org.apache.struts2.interceptor.RequestAware
があります。Actions コードに挿入されたこれらのデータマップのいずれかを取得するには、開発者は、インターフェイスで指定されたセッター (たとえば SessionAware
インターフェイスでは setSession
) を実装する必要があります。
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
、RequestAware
、ApplicationAware
のインターフェイスで示したように、影響を受けたインターフェイスを実装しているアプリケーションに対する巧妙なパラメーターを使用して、リモートの攻撃者が実行環境のデータ値を修正する可能性があります。
http://server/VulnerableAction?session.roles=admin
execute()
メソッドを上書きするエンドユーザーによって呼び出すことのできる public メソッドを開示します。execute()
以外のメソッドを開示できます。!
(感嘆符) 文字または method:
プレフィックスを Action URL に使用して、「Dynamic Method Invocation」が有効に設定されていれば Action でどの public メソッドでも呼び出すことができます。この機能を知らない開発者は、内部のビジネスロジックを攻撃者に対して無防備に開示してしまう可能性があります。http://server/app/recoverpassword!getPassword.action
org.apache.struts2.interceptor.ApplicationtAware
、org.apache.struts2.interceptor.SessionAware
、org.apache.struts2.interceptor.RequestAware
があります。Actions コードに挿入されたこれらのデータマップのいずれかを取得するには、開発者は、インターフェイスで指定されたセッター (たとえば SessionAware
インターフェイスでは setSession
) を実装する必要があります。
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
、RequestAware
、ApplicationAware
のインターフェイスで示したように、影響を受けたインターフェイスを実装しているアプリケーションに対する巧妙なパラメーターを使用して、リモートの攻撃者が実行環境のデータ値を修正する可能性があります。
http://server/VulnerableAction?session.roles=admin
org.apache.struts2.interceptor.ApplicationtAware
、org.apache.struts2.interceptor.SessionAware
、org.apache.struts2.interceptor.RequestAware
があります。Actions コードに挿入されたこれらのデータマップのいずれかを取得するには、開発者は、インターフェイスで指定されたセッター (たとえば SessionAware
インターフェイスでは setSession
) を実装する必要があります。
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
、RequestAware
、ApplicationAware
のインターフェイスで示したように、影響を受けたインターフェイスを実装しているアプリケーションに対する巧妙なパラメーターを使用して、リモートの攻撃者が実行環境のデータ値を修正する可能性があります。
http://server/VulnerableAction?session.roles=admin