...
var fs:FileStream = new FileStream();
fs.open(new File("config.properties"), FileMode.READ);
var decoder:Base64Decoder = new Base64Decoder();
decoder.decode(fs.readMultiByte(fs.bytesAvailable, File.systemCharset));
var password:String = decoder.toByteArray().toString();
URLRequestDefaults.setLoginCredentialsForHost(hostname, usr, password);
...
config.properties
にアクセスできる全員が password
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
string value = regKey.GetValue(passKey).ToString());
byte[] decVal = Convert.FromBase64String(value);
NetworkCredential netCred =
new NetworkCredential(username,decVal.toString(),domain);
...
password
の値を読み取れます。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
RegQueryValueEx(hkey, TEXT(.SQLPWD.), NULL,
NULL, (LPBYTE)password64, &size64);
Base64Decode(password64, size64, (BYTE*)password, &size);
rc = SQLConnect(*hdbc, server, SQL_NTS, uid,
SQL_NTS, password, SQL_NTS);
...
password64
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がパスワード情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
01 RECORDX.
05 UID PIC X(10).
05 PASSWORD PIC X(10).
05 LEN PIC S9(4) COMP.
...
EXEC CICS
READ
FILE('CFG')
INTO(RECORDX)
RIDFLD(ACCTNO)
...
END-EXEC.
CALL "g_base64_decode_inplace" using
BY REFERENCE PASSWORD
BY REFERENCE LEN
ON EXCEPTION
DISPLAY "Requires GLib library" END-DISPLAY
END-CALL.
EXEC SQL
CONNECT :UID
IDENTIFIED BY :PASSWORD
END-EXEC.
...
CFG
にアクセスできる全員がパスワードの値を読み取ることができ、値が base64 でエンコードされていることが分かります。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
file, _ := os.Open("config.json")
decoder := json.NewDecoder(file)
decoder.Decode(&values)
password := base64.StdEncoding.DecodeString(values.Password)
request.SetBasicAuth(values.Username, password)
...
config.json
にアクセスできる全員が password
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がパスワード情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
Properties prop = new Properties();
prop.load(new FileInputStream("config.properties"));
String password = Base64.decode(prop.getProperty("password"));
DriverManager.getConnection(url, usr, password);
...
config.properties
にアクセスできる全員が password
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
webview.setWebViewClient(new WebViewClient() {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
String username = new String(Base64.decode(credentials[0], DEFAULT));
String password = new String(Base64.decode(credentials[1], DEFAULT));
handler.proceed(username, password);
}
});
...
...
obj = new XMLHttpRequest();
obj.open('GET','/fetchusers.jsp?id='+form.id.value,'true','scott','tiger');
...
plist
ファイルからパスワードを読み取り、読み取ったパスワードを使用してパスワードで保護されたファイルを解凍します。
...
NSDictionary *dict= [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"]];
NSString *encoded_password = [dict valueForKey:@"encoded_password"];
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:encoded_password options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
[SSZipArchive unzipFileAtPath:zipPath toDestination:destPath overwrite:TRUE password:decodedString error:&error];
...
Config.plist
ファイルにアクセスできる全員が encoded_password
の値を読むことができ、値が base64 でエンコードされていることが分かります。
...
$props = file('config.properties', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$password = base64_decode($props[0]);
$link = mysql_connect($url, $usr, $password);
if (!$link) {
die('Could not connect: ' . mysql_error());
}
...
config.properties
にアクセスできる全員が password
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
props = os.open('config.properties')
password = base64.b64decode(props[0])
link = MySQLdb.connect (host = "localhost",
user = "testuser",
passwd = password,
db = "test")
...
config.properties
にアクセスできる全員が password
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
require 'pg'
require 'base64'
...
passwd = Base64.decode64(ENV['PASSWD64'])
...
conn = PG::Connection.new(:dbname => "myApp_production", :user => username, :password => passwd, :sslmode => 'require')
PASSWD64
の値を読み取り、その値が base64 でエンコードされていることを容易に判断できます。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
val prop = new Properties();
prop.load(new FileInputStream("config.properties"));
val password = Base64.decode(prop.getProperty("password"));
DriverManager.getConnection(url, usr, password);
...
config.properties
にアクセスできる全員がpassword
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がパスワード情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。plist
ファイルからパスワードを読み取り、読み取ったパスワードを使用してパスワードで保護されたファイルを解凍します。
...
var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
let password = base64decode(dict["encoded_password"])
zipArchive.unzipOpenFile(zipPath, password:password])
}
...
Config.plist
ファイルにアクセスできる全員が encoded_password
の値を読むことができ、値が base64 でエンコードされていることが分かります。
...
root:qFio7llfVKk.s:19033:0:99999:7:::
...
...
...
Private Declare Function GetPrivateProfileString _
Lib "kernel32" Alias "GetPrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, ByVal lpDefault As String, _
ByVal lpReturnedString As String, ByVal nSize As Long, _
ByVal lpFileName As String) As Long
...
Dim password As String
...
password = StrConv(DecodeBase64(GetPrivateProfileString("MyApp", "Password", _
"", value, Len(value), _
App.Path & "\" & "Config.ini")), vbUnicode)
...
con.ConnectionString = "Driver={Microsoft ODBC for Oracle};Server=OracleServer.world;Uid=scott;Passwd=" & password &";"
...
Config.ini
にアクセスできる全員が Password
の値を読むことができ、値が base64 でエンコードされていることが分かります。不心得な従業員がこの情報へのアクセス権を持っている場合、システムに侵入するために使用されることがあります。
...
*Get the report that is to be deleted
r_name = request->get_form_field( 'report_name' ).
CONCATENATE `C:\\users\\reports\\` r_name INTO dsn.
DELETE DATASET dsn.
...
..\\..\\usr\\sap\\DVEBMGS00\\exe\\disp+work.exe
" のようなファイル名を指定した場合、アプリケーションで重要なファイルが削除され、SAP システムが直ちにクラッシュします。
...
PARAMETERS: p_date TYPE string.
*Get the invoice file for the date provided
CALL FUNCTION 'FILE_GET_NAME'
EXPORTING
logical_filename = 'INVOICE'
parameter_1 = p_date
IMPORTING
file_name = v_file
EXCEPTIONS
file_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
OPEN DATASET v_file FOR INPUT IN TEXT MODE.
DO.
READ DATASET v_file INTO v_record.
IF SY-SUBRC NE 0.
EXIT.
ELSE.
WRITE: / v_record.
ENDIF.
ENDDO.
...
..\\..\\usr\\sap\\sys\\profile\\default.pfl
" のような文字列を指定した場合、アプリケーションでデフォルトの SAP アプリケーション サーバー プロファイルのパラメーター設定のすべてが表示され、より巧妙な攻撃を招く可能性があります。../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルの入力を使用して、開くファイルを判断し、「デバッグ」コンソールまたはログファイルに書き込みます。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var rName:String = String(params["reportName"]);
var rFile:File = new File("/usr/local/apfr/reports/" + rName);
...
rFile.deleteFile();
.txt
のすべてのファイルをシステムから読み取ることができます。
var fs:FileStream = new FileStream();
fs.open(new File(String(configStream.readObject())+".txt"), FileMode.READ);
fs.readBytes(arr);
trace(arr);
public class MyController {
...
public PageRerference loadRes() {
PageReference ref = ApexPages.currentPage();
Map<String,String> params = ref.getParameters();
if (params.containsKey('resName')) {
if (params.containsKey('resPath')) {
return PageReference.forResource(params.get('resName'), params.get('resPath'));
}
}
return null;
}
}
..\\..\\Windows\\System32\\krnl386.exe
」のようなファイル名を入力することによって、重要な Windows のシステム ファイルが削除される可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが適切な権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が .txt のすべてのファイルをシステムから読み取ることができます。
String rName = Request.Item("reportName");
...
File.delete("C:\\users\\reports\\" + rName);
sr = new StreamReader(resmngr.GetString("sub")+".txt");
while ((line = sr.ReadLine()) != null) {
Console.WriteLine(line);
}
../../apache/conf/httpd.conf
」などのファイル名を指定することによって、特定の設定ファイルを削除させる可能性があることを考慮していません。例 2: 次のコードでは、コマンドラインによる入力を使って開くファイルを決定し、ユーザーに通知しています。プログラムが適切な権限付きで実行される場合に悪意あるユーザーがファイルへのソフトリンクを作成すると、そのユーザーはプログラムを利用してシステム上の任意のファイルの冒頭部分を読み取ることができます。
char* rName = getenv("reportName");
...
unlink(rName);
ifstream ifs(argv[0]);
string s;
ifs >> s;
cout << s;
...
EXEC CICS
WEB READ
FORMFIELD(FILE)
VALUE(FILENAME)
...
END-EXEC.
EXEC CICS
READ
FILE(FILENAME)
INTO(RECORD)
RIDFLD(ACCTNO)
UPDATE
...
END-EXEC.
...
..\\..\\Windows\\System32\\krnl386.exe
」のようなファイル名を入力することによって、重要な Windows のシステムファイルの削除を引き起こす可能性を考慮していません。
<cffile action = "delete"
file = "C:\\users\\reports\\#Form.reportName#">
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final headers = request.headers;
final path = headers.value('path');
File(path!).delete();
}
Example 1
では、ファイルの削除関数を実行する前に headers.value('path')
の検証は行われません。../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
rName := "/usr/local/apfr/reports/" + req.FormValue("fName")
rFile, err := os.OpenFile(rName, os.O_RDWR|os.O_CREATE, 0755)
defer os.Remove(rName);
defer rFile.Close()
...
.txt
のすべてのファイルをシステムから読み取ることができます。
...
config := ReadConfigFile()
filename := config.fName + ".txt";
data, err := ioutil.ReadFile(filename)
...
fmt.Println(string(data))
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
String rName = request.getParameter("reportName");
File rFile = new File("/usr/local/apfr/reports/" + rName);
...
rFile.delete();
.txt
のすべてのファイルをシステムから読み取ることができます。
fis = new FileInputStream(cfg.getProperty("sub")+".txt");
amt = fis.read(arr);
out.println(arr);
Example 1
を応用しています。
...
String rName = this.getIntent().getExtras().getString("reportName");
File rFile = getBaseContext().getFileStreamPath(rName);
...
rFile.delete();
...
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードでは、ローカル ストレージからの入力を使って開くファイルを決定し、ユーザーに通知しています。悪意あるユーザーがローカル ストレージの内容を変更できてしまう場合、プログラムを使用して、拡張子
...
var reportNameParam = "reportName=";
var reportIndex = document.indexOf(reportNameParam);
if (reportIndex < 0) return;
var rName = document.URL.substring(reportIndex+reportNameParam.length);
window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
fs.root.getFile('/usr/local/apfr/reports/' + rName, {create: false}, function(fileEntry) {
fileEntry.remove(function() {
console.log('File removed.');
}, errorHandler);
}, errorHandler);
}, errorHandler);
.txt
で終わるシステム上の任意のファイルを読み取ることができます。
...
var filename = localStorage.sub + '.txt';
function oninit(fs) {
fs.root.getFile(filename, {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var txtArea = document.createElement('textarea');
txtArea.value = this.result;
document.body.appendChild(txtArea);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
window.requestFileSystem(window.TEMPORARY, 1024*1024, oninit, errorHandler);
...
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
val rName: String = request.getParameter("reportName")
val rFile = File("/usr/local/apfr/reports/$rName")
...
rFile.delete()
.txt
のすべてのファイルをシステムから読み取ることができます。
fis = FileInputStream(cfg.getProperty("sub").toString() + ".txt")
amt = fis.read(arr)
out.println(arr)
Example 1
を応用しています。
...
val rName: String = getIntent().getExtras().getString("reportName")
val rFile: File = getBaseContext().getFileStreamPath(rName)
...
rFile.delete()
...
- (NSData*) testFileManager {
NSString *rootfolder = @"/Documents/";
NSString *filePath = [rootfolder stringByAppendingString:[fileName text]];
NSFileManager *fm = [NSFileManager defaultManager];
return [fm contentsAtPath:filePath];
}
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
$rName = $_GET['reportName'];
$rFile = fopen("/usr/local/apfr/reports/" . rName,"a+");
...
unlink($rFile);
.txt
のすべてのファイルをシステムから読み取ることができます。
...
$filename = $CONFIG_TXT['sub'] . ".txt";
$handle = fopen($filename,"r");
$amt = fread($handle, filesize($filename));
echo $amt;
...
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
rName = req.field('reportName')
rFile = os.open("/usr/local/apfr/reports/" + rName)
...
os.unlink(rFile);
.txt
のすべてのファイルをシステムから読み取ることができます。
...
filename = CONFIG_TXT['sub'] + ".txt";
handle = os.open(filename)
print handle
...
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
rName = req['reportName']
File.delete("/usr/local/apfr/reports/#{rName}")
.txt
のすべてのファイルをシステムから読み取ることができます。
...
fis = File.new("#{cfg.getProperty("sub")}.txt")
amt = fis.read
puts amt
../../tomcat/conf/server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
def readFile(reportName: String) = Action { request =>
val rFile = new File("/usr/local/apfr/reports/" + reportName)
...
rFile.delete()
}
.txt
のすべてのファイルをシステムから読み取ることができます。
val fis = new FileInputStream(cfg.getProperty("sub")+".txt")
val amt = fis.read(arr)
out.println(arr)
func testFileManager() -> NSData {
let filePath : String = "/Documents/\(fileName.text)"
let fm : NSFileManager = NSFileManager.defaultManager()
return fm.contentsAtPath(filePath)
}
..\conf\server.xml
」などのファイル名を指定し、アプリケーションでいずれかの設定ファイルを削除することができる可能性を考慮していません。例 2: 次のコードは設定ファイルからの入力を使用して、開くファイルを判断し、ユーザーに通知しています。プログラムが権限付きで実行されていると、悪意あるユーザーが設定ファイルを変更できる場合、プログラムを変更して拡張子が
Dim rName As String
Dim fso As New FileSystemObject
Dim rFile as File
Set rName = Request.Form("reportName")
Set rFile = fso.GetFile("C:\reports\" & rName)
...
fso.DeleteFile("C:\reports\" & rName)
...
.txt
のすべてのファイルをシステムから読み取ることができます。
Dim fileName As String
Dim tsContent As String
Dim ts As TextStream
Dim fso As New FileSystemObject
fileName = GetPrivateProfileString("MyApp", "sub", _
"", value, Len(value), _
App.Path & "\" & "Config.ini")
...
Set ts = fso.OpenTextFile(fileName,1)
tsContent = ts.ReadAll
Response.Write tsContent
...
Path.Combine
は引数としていくつかのファイル パスを取ります。 ファイル パスを連結して完全パスを取得します。通常は、その後でファイルに対する read()
または write()
を呼び出します。 ドキュメントには、最初のパラメーターまたは残りのパラメーターが絶対パスかどうかに基づいて、いくつかの異なるシナリオが記述されています。 2 番目または残りのパラメーターが絶対パスの場合、Path.Combine()
はその絶対パスを返します。 以前のパラメーターは無視されます。 次の例のようなコードを持つアプリケーションでは、これは重要な意味を持っています。
// Called with user-controlled data
public static bytes[] getFile(String filename)
{
String imageDir = "\\FILESHARE\images\";
filepath = Path.Combine(imageDir, filename);
return File.ReadAllBytes(filepath);
}
C:\\inetpub\wwwroot\web.config
)を指定することで、攻撃者はアプリケーションにより返されるファイルを制御できます。
...
" Add Binary File to
CALL METHOD lr_abap_zip->add
EXPORTING
name = p_ifile
content = lv_bufferx.
" Read Binary File to
CALL METHOD lr_abap_zip->get
EXPORTING
name = p_ifile
IMPORTING
content = lv_bufferx2.
...
Example 1
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に p_ifile
の検証が行われていません。ZIP ファイルが元は Unix ベースのマシンのディレクトリ「/tmp/
」に格納されていて、ZIP エントリが「../etc/hosts
」で、アプリケーションが適切な権限で実行された場合、システムの hosts
ファイルが上書きされます。そのため、攻撃者はこのマシンからのトラフィックを、攻撃者自身のマシンなどいかなる場所にでも誘導することができます。
public static void UnzipFile(ZipArchive archive, string destDirectory)
{
foreach (var entry in archive.Entries)
{
string file = entry.FullName;
if (!string.IsNullOrEmpty(file))
{
string destFileName = Path.Combine(destDirectory, file);
entry.ExtractToFile(destFileName, true);
}
}
}
Example 1
では、エントリ内のデータに対して読み取り/書き込み操作を実行する前に entry.FullName
の検証が行われていません。Zip ファイルがディレクトリ「C:\TEMP
」に元々格納され、Zip エントリ名に「..\
セグメント」が含まれ、アプリケーションが適切な権限で実行された場合、システム ファイルを任意に上書きできることを意味します。
func Unzip(src string, dest string) ([]string, error) {
var filenames []string
r, err := zip.OpenReader(src)
if err != nil {
return filenames, err
}
defer r.Close()
for _, f := range r.File {
// Store filename/path for returning and using later on
fpath := filepath.Join(dest, f.Name)
filenames = append(filenames, fpath)
if f.FileInfo().IsDir() {
// Make Folder
os.MkdirAll(fpath, os.ModePerm)
continue
}
// Make File
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
return filenames, err
}
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return filenames, err
}
rc, err := f.Open()
if err != nil {
return filenames, err
}
_, err = io.Copy(outFile, rc)
// Close the file without defer to close before next iteration of loop
outFile.Close()
rc.Close()
if err != nil {
return filenames, err
}
}
return filenames, nil
}
Example 1
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に f.Name
の検証が行われていません。Zip ファイルが元は Unix ベースのマシンのディレクトリ「/tmp/
」に格納されていて、Zip エントリが「../etc/hosts
」で、アプリケーションが適切な権限で実行された場合、システムの hosts
ファイルが上書きされます。そのため、攻撃者はこのマシンからのトラフィックを、攻撃者自身のマシンなどいかなる場所にでも誘導することができます。
private static final int BUFSIZE = 512;
private static final int TOOBIG = 0x640000;
...
public final void unzip(String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry zipEntry = null;
int numOfEntries = 0;
long total = 0;
try {
while ((zipEntry = zis.getNextEntry()) != null) {
byte data[] = new byte[BUFSIZE];
int count = 0;
String outFileName = zipEntry.getName();
if (zipEntry.isDirectory()){
new File(outFileName).mkdir(); //create the new directory
continue;
}
FileOutputStream outFile = new FileOutputStream(outFileName);
BufferedOutputStream dest = new BufferedOutputStream(outFile, BUFSIZE);
//read data from Zip, but do not read huge entries
while (total + BUFSIZE <= TOOBIG && (count = zis.read(data, 0, BUFSIZE)) != -1) {
dest.write(data, 0, count);
total += count;
}
...
}
} finally{
zis.close();
}
}
...
Example 1
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に zipEntry.getName()
の検証が行われていません。Zip ファイルが元は Unix ベースのマシンのディレクトリ「/tmp/
」に格納されていて、Zip エントリが「../etc/hosts
」で、アプリケーションが適切な権限で実行された場合、システムの hosts
ファイルが上書きされます。そのため、攻撃者はこのマシンからのトラフィックを、攻撃者自身のマシンなどいかなる場所にでも誘導することができます。
var unzipper = require('unzipper');
var fs = require('fs');
var untrusted_zip = getZipFromRequest();
fs.createReadStream(zipPath).pipe(unzipper.Extract({ path: 'out' }));
ZZArchive* archive = [ZZArchive archiveWithURL:[NSURL fileURLWithPath: zipPath] error:&error];
for (ZZArchiveEntry* entry in archive.entries) {
NSString *fullPath = [NSString stringWithFormat: @"%@/%@", destPath, [entry fileName]];
[[entry newDataWithError:nil] writeToFile:newFullPath atomically:YES];
}
Example 1
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に entry.fileName
の検証が行われていません。Zip ファイルが iOS アプリケーションのディレクトリ「Documents/hot_patches
」に元々格納され、Zip エントリが「../js/page.js
」の場合、page.js
ファイルが上書きされます。これにより、攻撃者が悪意あるコードを挿入してコードを実行することを許してしまう可能性があります。
...
$zip = new ZipArchive();
$zip->open("userdefined.zip", ZipArchive::RDONLY);
$zpm = $zip->getNameIndex(0);
$zip->extractTo($zpm);
...
Example 1
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に f.Name
の検証が行われていません。Zip ファイルが Unix ベースのマシンのディレクトリ「/tmp/
」にあり、Zip エントリが「../etc/hosts
」で、アプリケーションが適切な権限で実行された場合、システムの hosts
ファイルが上書きされます。そのため、攻撃者はこのマシンからのトラフィックを、攻撃者自身のマシンなどいかなる場所にでも誘導することができます。
import zipfile
import tarfile
def unzip(archive_name):
zf = zipfile.ZipFile(archive_name)
zf.extractall(".")
zf.close()
def untar(archive_name):
tf = tarfile.TarFile(archive_name)
tf.extractall(".")
tf.close()
例 2: 次の例では、Zip ファイルからファイルを抽出し、安全でない方法でディスクに書き込んでいます。
import better.files._
...
val zipPath: File = getUntrustedZip()
val destinationPath = file"out/dest"
zipPath.unzipTo(destination = destinationPath)
import better.files._
...
val zipPath: File = getUntrustedZip()
val destinationPath = file"out/dest"
zipPath.newZipInputStream.mapEntries( (entry : ZipEntry) => {
entry.extractTo(destinationPath, new FileInputStream(entry.getName))
})
Example 2
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に entry.getName
の検証が行われていません。Zip ファイルが元は Unix ベースのマシンのディレクトリ「/tmp/
」に格納されていて、Zip エントリが「../etc/hosts
」で、アプリケーションが適切な権限で実行された場合、システムの hosts
ファイルが上書きされます。そのため、攻撃者はこのマシンからのトラフィックを、攻撃者自身のマシンなどいかなる場所にでも誘導することができます。
let archive = try ZZArchive.init(url: URL(fileURLWithPath: zipPath))
for entry in archive.entries {
let fullPath = URL(fileURLWithPath: destPath + "/" + entry.fileName)
try entry.newData().write(to: fullPath)
}
Example 1
では、そのエントリ内のデータに対して読み取り/書き込み機能を実行する前に entry.fileName
の検証が行われていません。Zip ファイルが iOS アプリケーションのディレクトリ「Documents/hot_patches
」に元々格納され、Zip エントリが「../js/page.js
」の場合、page.js
ファイルが上書きされます。これにより、攻撃者が悪意あるコードを挿入してコードを実行することを許してしまう可能性があります。FileIOPermissions
を決定します。
...
String permissionsXml = GetPermissionsFromXmlFile();
FileIOPermission perm = new FileIOPermission(PermissionState.None);
perm.FromXml(permissionsXml);
perm.Demand();
...
...
CrytoKeyAuditRule auditRule = new CryptoKeyAuditRule(IdRef, (CryptoKeyRights) input, AuditFlags.Success);
...
input
を制御できる場合、記録できる操作のタイプを指定できます。ユーザーはこれを CryptoKeyRights.Delete
に操作できる場合、暗号鍵を記録せずに読み取ることができる可能性があり、これにより攻撃者が暗号鍵を盗んだことに気付きません。doExchange()
からの例外を無視します。
try {
doExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
が仮にスローされても、プログラムは、何の異常も発生しなかったかのように実行を続けます。プログラムは、特殊な状況を示す証拠を何も記録しないため、後でプログラムの動作を説明しようとしてもうまくいかない可能性があります。DoExchange()
で稀に発生する例外を無視しています。
try {
DoExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
が発生しても、プログラムは異常が発生しなかったかのように継続して実行されます。プログラムは特別な状況を示す証拠を記録しないため、プログラムの動作を後で調べようとする場合に苛立ちを感じることもあります。doExchange()
で稀に発生する例外を無視しています。
try {
doExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
が発生しても、プログラムは異常が発生しなかったかのように継続して実行されます。プログラムは特別な状況を示す証拠を記録しないため、プログラムの動作を後で調べようとする場合に苛立ちを感じることもあります。doExchange()
で稀に発生する例外を無視しています。
try {
doExchange();
}
catch (exception $e) {
// this can never happen
}
RareException
が発生しても、プログラムは異常が発生しなかったかのように継続して実行されます。プログラムは特別な状況を示す証拠を記録しないため、プログラムの動作を後で調べようとする場合に苛立ちを感じることもあります。open()
で稀に発生する例外を無視しています。
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except:
# This will never happen
pass
RareException
が発生しても、プログラムは異常が発生しなかったかのように継続して実行されます。プログラムは特別な状況を示す証拠を記録しないため、プログラムの動作を後で調べようとする場合に苛立ちを感じることもあります。Exception
などの高レベルクラスをキャッチすることで catch ブロックを「簡略化」すると、特別な処理が必要な例外やプログラムのこの時点ではキャッチすべきでない例外が不明確になります。キャッチする例外があまりに広範にわたると、本質的に .NET の入力例外の目的にそぐわなくなるだけでなく、プログラムが新しいタイプの例外を発生させるようになると特に危険になります。新しい例外タイプは特に注意されません。
try {
DoExchange();
}
catch (IOException e) {
logger.Error("DoExchange failed", e);
}
catch (FormatException e) {
logger.Error("DoExchange failed", e);
}
catch (TimeoutException e) {
logger.Error("DoExchange failed", e);
}
try {
DoExchange();
}
catch (Exception e) {
logger.Error("DoExchange failed", e);
}
DoExchange()
を変更した場合、広範囲な catch ブロックのためにコンパイラは状況を指摘することができません。さらに、プログラマの意図に反して、新しい catch ブロックは ApplicationException
や NullReferenceException
からの例外も扱うようになります。Exception
などの高レベルクラスをキャッチすることで catch ブロックを「簡略化」すると、特別な処理が必要な例外やプログラムのこの時点ではキャッチすべきでない例外が不明確になります。キャッチする例外があまりに広範にわたると、本質的に Java の入力例外の目的にそぐわなくなるだけでなく、プログラムが新しいタイプの例外を発生させるようになり特に危険になります。新しい例外タイプは特に注意されません。
try {
doExchange();
}
catch (IOException e) {
logger.error("doExchange failed", e);
}
catch (InvocationTargetException e) {
logger.error("doExchange failed", e);
}
catch (SQLException e) {
logger.error("doExchange failed", e);
}
try {
doExchange();
}
catch (Exception e) {
logger.error("doExchange failed", e);
}
doExchange()
を変更した場合、広範囲な catch ブロックのためにコンパイラは状況を指摘することができません。さらに、プログラマの意図に反して、新しい catch ブロックは ClassCastException
や NullPointerException
などの RuntimeException
からの例外も扱うようになります。NullReferenceException
をキャッチすることは一般に良くない方法です。NullReferenceException
をキャッチします。NullReferenceException
を発生させる場合。NullReferenceException
を誤ってキャッチしています。
try {
MysteryMethod();
}
catch (NullReferenceException npe) {
}
Console.Out
または Console.Error
を使用すると、プログラムの動作を監視することが困難になります。
public class MyClass {
...
Console.WriteLine("hello world");
...
}
Console.WriteLine()
を使って標準出力にメッセージを書いている場合が驚くほど多く見受けられます。Console.WriteLine
が使用されている場合は、構造化ロギングシステムへの移行で何かが見落とされている可能性があります。os.Stdout
または os.Stderr
を使用すると、プログラムの動作を監視することが困難になります。
...
func foo(){
fmt.Println("Hello World")
}
fmt.Println()
を使って標準出力にメッセージを出力することを止めない開発者もいます。os.Stdout
または os.Stderr
へのロギングが使用されている場合は、構造化ロギング システムへの移行で何かが見落とされている可能性があります。System.out
または System.err
を使用すると、プログラムの動作を監視することが困難になります。
public class MyClass
...
System.out.println("hello world");
...
}
System.out.println()
を使って標準出力にメッセージを書いている場合が驚くほど多く見受けられます。System.out
または System.err
が使用されている場合は、構造化ロギングシステムへの移行で何かが見落とされている可能性があります。process.stdout
または process.stderr
を使用すると、プログラムの動作を監視することが困難になります。
process.stdin.on('readable', function(){
var s = process.stdin.read();
if (s != null){
process.stdout.write(s);
}
});
process.stdout.write()
を使って標準出力にメッセージを記述することから離れようとはしません。process.stdout
または process.stderr
が使用されている場合は、構造化ロギングシステムへの移行で何かが見落とされている可能性があります。print
または println
を使用すると、プログラムの動作を監視することが困難になります。
class MyClass {
...
println("hello world")
...
}
}
print
または println
を使って標準出力にメッセージを書いている場合が驚くほど多く見受けられます。
sys.stdout.write("hello world")
sys.stdout
または sys.stderr
が使用されている場合は、構造化ロギングシステムへの移行で何かが見落とされている可能性があります。Kernel.puts
、Kernel.warn
、または Kernel.printf
を使用すると、プログラムの動作を監視することが困難になります。
...
puts "hello world"
...
Kernel.puts
を使って標準出力にメッセージを書いている場合が驚くほど多く見受けられます。Kernel.puts
、Kernel.warn
、または Kernel.printf
が使用されている場合は、構造化ロギングシステムへの移行で何かが見落とされている可能性があります。Logger
クラスを使用しますが、情報をシステム出力ストリームに記録します。
require 'logger'
...
logger = Logger.new($stdout)
logger.info("hello world")
...
...
var file:File = new File(directoryName + "\\" + fileName);
...
...
FileStream f = File.Create(directoryName + "\\" + fileName);
...
...
File file = new File(directoryName + "\\" + fileName);
...
...
os.open(directoryName + "\\" + fileName);
...
...
uid = 'scott'.
password = 'tiger'.
WRITE: / 'Default username for FTP connection is: ', uid.
WRITE: / 'Default password for FTP connection is: ', password.
...
pass = getPassword();
...
trace(id+":"+pass+":"+type+":"+tstamp);
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
...
ResetPasswordResult passRes = System.resetPassword(id1, true);
System.Debug('New password: '+passRes.getPassword());
...
pass = GetPassword();
...
dbmsLog.WriteLine(id+":"+pass+":"+type+":"+tstamp);
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。get_password()
関数は、アカウントに関連付けられたパスワードを、ユーザーが入力した平文で返します。
pass = get_password();
...
fprintf(dbms_log, "%d:%s:%s:%s", id, pass, type, tstamp);
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。開発者の多くは、ファイル システムをあらゆるデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
...
MOVE "scott" TO UID.
MOVE "tiger" TO PASSWORD.
DISPLAY "Default username for database connection is: ", UID.
DISPLAY "Default password for database connection is: ", PASSWORD.
...
Session.pword
変数にはアカウントに関連付けられた平文のパスワードが含まれます。
<cflog file="app_log" application="No" Thread="No"
text="#Session.uname#:#Session.pword#:#type#:#Now()#">
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
var pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。GetPassword()
関数からの戻り値であり、アカウントに関連付けられるパスワードをユーザーが入力した平文で返します。
pass = GetPassword();
...
if err != nil {
log.Printf('%s: %s %s %s', id, pass, type, tsstamp)
}
Example 1
のコードでは、平文のパスワードがアプリケーション イベント ログに記録されています。多くの開発者がイベントログをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
...
webview.setWebViewClient(new WebViewClient() {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
String username = credentials[0];
String password = credentials[1];
Intent i = new Intent();
i.setAction("SEND_CREDENTIALS");
i.putExtra("username", username);
i.putExtra("password", password);
view.getContext().sendBroadcast(i);
}
});
...
SEND_CREDENTIALS
アクションによってインテントに接続リクエストを行うように登録済みの受信者の誰もがメッセージを受信することを意味します。この開示は受信者数を制限する許可によっても保護されませんが、この場合対策として許可を使用することは推奨されません。
localStorage.setItem('password', password);
pass = getPassword()
...
dbmsLog.println("$id:$pass:$type:$tstamp")
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
...
webview.webViewClient = object : WebViewClient() {
override fun onReceivedHttpAuthRequest(view: WebView,
handler: HttpAuthHandler, host: String, realm: String
) {
val credentials = view.getHttpAuthUsernamePassword(host, realm)
val username = credentials!![0]
val password = credentials[1]
val i = Intent()
i.action = "SEND_CREDENTIALS"
i.putExtra("username", username)
i.putExtra("password", password)
view.context.sendBroadcast(i)
}
}
...
SEND_CREDENTIALS
アクションによってインテントに接続リクエストを行うように登録済みの受信者の誰もがメッセージを受信することを意味します。この開示は受信者数を制限する許可によっても保護されませんが、この場合対策として許可を使用することは推奨されません。
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
// Configure the new event with information from the location
CLLocationCoordinate2D coordinate = [location coordinate];
NSString *latitude = [NSString stringWithFormat:@"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:@"%f", coordinate.longitude];
NSLog(@"dLatitude : %@", latitude);
NSLog(@"dLongitude : %@",longitude);
NSString *urlWithParams = [NSString stringWithFormat:TOKEN_URL, latitude, longitude];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlWithParams]];
[request setHTTPMethod:@"GET"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Add password to user defaults
[defaults setObject:@"Super Secret" forKey:@"passwd"];
[defaults synchronize];
getPassword()
関数からの戻り値です。
<?php
$pass = getPassword();
trigger_error($id . ":" . $pass . ":" . $type . ":" . $tstamp);
?>
Example 1
のコードでは、平文のパスワードがアプリケーションイベントログに記録されています。多くの開発者がイベントログをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。OWA_SEC.get_password()
関数がアカウントに関連付けられているユーザー入力の平文パスワードを返すと、そのパスワードが HTTP レスポンスに出力されます。
...
HTP.htmlOpen;
HTP.headOpen;
HTP.title (.Account Information.);
HTP.headClose;
HTP.bodyOpen;
HTP.br;
HTP.print('User ID: ' ||
OWA_SEC.get_user_id || '');
HTP.print('User Password: ' ||
OWA_SEC.get_password || '');
HTP.br;
HTP.bodyClose;
HTP.htmlClose;
...
getPassword()
関数からの戻り値です。
pass = getPassword();
logger.warning('%s: %s %s %s', id, pass, type, tsstamp)
Example 1
のコードでは、平文のパスワードがアプリケーションイベントログに記録されています。多くの開発者がイベントログをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。get_password()
関数は、格納される値のうち、アカウントのパスワードをユーザーが入力した平文で戻します。
pass = get_password()
...
dbms_logger.warn("#{id}:#{pass}:#{type}:#{tstamp}")
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
val pass = getPassword()
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp)
Example 1
のコードでは、平文のパスワードがファイルシステムに記録されています。多くの開発者がファイルシステムをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
import CoreLocation
...
var locationManager : CLLocationManager!
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
...
if let location: CLLocation! = locationManager.location {
var coordinate : CLLocationCoordinate2D = location.coordinate
let latitude = NSString(format:@"%f", coordinate.latitude)
let longitude = NSString(format:@"%f", coordinate.longitude)
NSLog("dLatitude : %@", latitude)
NSLog("dLongitude : %@",longitude)
let urlString : String = "http://myserver.com/?lat=\(latitude)&lon=\(longitude)"
let url : NSURL = NSURL(string:urlString)
let request : NSURLRequest = NSURLRequest(URL:url)
var err : NSError?
var response : NSURLResponse?
var data : NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error:&err)
} else {
println("no location...")
}
let defaults : NSUserDefaults = NSUserDefaults.standardUserDefaults()
// Add password to user defaults
defaults.setObject("Super Secret" forKey:"passwd")
defaults.synchronize()
getPassword
関数は、アカウントに関連付けられたパスワードを、ユーザーが入力した平文で返します。
pass = getPassword
...
App.EventLog id & ":" & pass & ":" & type & ":" &tstamp, 4
...
Example 1
のコードでは、平文のパスワードがアプリケーションイベントログに記録されています。多くの開発者がイベントログをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。
...
HKHealthStore healthStore = new HKHealthStore();
HKBloodTypeObject blood = healthStore.GetBloodType(null);
NSLog("%@", blood.BloodType);
var urlWithParams = String.format(TOKEN_URL, block.BloodType);
var responseString = await client.GetStringAsync(urlWithParams);
...
NSLog
関数よりも下位にあり、開発者はデバイス上のすべてのログを読み取ることのできるアプリケーションを作成できます (他のアプリケーションを所有していない場合でも)。
...
HKHealthStore healthStore = new HKHealthStore();
HKBloodTypeObject blood = healthStore.GetBloodType(null);
// Add blood type to user defaults
NSUserDefaults.StandardUserDefaults.SetString(blood.BloodType, "bloodType");
...
...
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
HKBloodTypeObject *blood = [healthStore bloodTypeWithError:nil];
NSLog(@"%@", [blood bloodType]);
NSString *urlWithParams = [NSString stringWithFormat:TOKEN_URL, [blood bloodType]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlWithParams]];
[request setHTTPMethod:@"GET"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
...
NSLog
関数よりも下位にあり、開発者はデバイス上のすべてのログを読み取ることのできるアプリケーションを作成できます (他のアプリケーションを所有していない場合でも)。
...
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
HKBloodTypeObject *blood = [healthStore bloodTypeWithError:nil];
// Add blood type to user defaults
[defaults setObject:[blood bloodType] forKey:@"bloodType"];
[defaults synchronize];
...
...
let healthStore = HKHealthStore()
let blood = try healthStore.bloodType()
print(blood.bloodType)
let urlString : String = "http://myserver.com/?data=\(blood.bloodType)"
let url : NSURL = NSURL(string:urlString)
let request : NSURLRequest = NSURLRequest(URL:url)
var err : NSError?
var response : NSURLResponse?
var data : NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error:&err)
...
NSLog
関数よりも下位にあり、開発者はデバイス上のすべてのログを読み取ることのできるアプリケーションを作成できます (他のアプリケーションを所有していない場合でも)。
...
let healthStore = HKHealthStore()
let blood = try healthStore.bloodType()
print(blood.bloodType)
// Add blood type to user defaults
defaults.setObject("BloodType" forKey:blood.bloodType)
defaults.synchronize()
...
String
オブジェクトに保存します。
public static String getPassword() {
String inputPassword = "";
ConsoleKeyInfo nextKey = Console.ReadKey(true);
while (nextKey.Key != Console.ReadKey(true)) {
inputPassword.AppendChar(nextKey.KeyChar);
Console.Write("*");
nextKey = Console.ReadKey(true);
}
return inputPassword;
}
String
は不変のオブジェクトであるため、内容を無効化することはできません。つまり、機密データは、ガベージ コレクションを行う前にヒープを検査できるすべてのユーザーに公開されます。String
オブジェクトに重要なデータを保存すると、メモリからデータを確実に消去できません。String
は重要データの保存に使用されます。ただし、String
オブジェクトは不変であるため、メモリから String
の値を削除できるのは JVM ガベージ コレクターのみです。JVM のメモリが不足しない限り、ガベージ コレクターを実行する必要はありません。そのため、ガベージ コレクションがいつ行われるかについては保証されません。アプリケーションがクラッシュすると、アプリケーションのメモリ ダンプによって重要データが明らかになる場合があります。String
にパスワードを変換しています。
private JPasswordField pf;
...
final char[] password = pf.getPassword();
...
String passwordAsString = new String(password);
String
オブジェクトに重要なデータを保存すると、メモリからデータを確実に消去できません。String
は機密データを保管するために使用されますが、String
オブジェクトは不変であるため、それらに新しい値を割り当てると新しいString
が作成され、割り当てられているオブジェクトにその参照が割り当てられます。ARC
(Automatic Reference Counting) がオブジェクトの割り当てを解除してそのメモリを解放するまで、元の値はメモリに残ります。Swift は、最も近い周囲のスコープが終了するまで、オブジェクトの存続期間について保証しません。オブジェクトの割り当てが解除される前に攻撃者がメモリの内容をダンプすると、その内容を読み取ることができます。String
を使用してパスワードをメモリに保管します。
let password = passwordTextField.text!
// use the password
SensitiveXMLData
から重要な財務情報のグラフを生成する、DataVisualization
コントロールを開始しています。
<asp:Chart ID="Chart1" runat="server" ImageLocation="~/Temporary/Graph"
ImageType="Jpeg" DataSourceID="SensitiveXMLData" ImageStorageMode="UseImageLocation">
<series>
.
.
.
</series>
<chartareas>
<asp:ChartArea Name="ChartArea1">
</asp:ChartArea>
</chartareas>
</asp:Chart>
Example 1
のコードは、Chart
コントロールに棒グラフの JPEG 画像を生成し、その画像をテンポラリ ディレクトリ ~/Temporary/Graph
に書き込むように命令しています。このコントロールにより画像がディスクに書き込まれると、ユーザーのブラウザに後でファイルを表示するクエストがあると、このファイルがユーザーに表示されます。画像は安全な方法でディスクに書き込まれません。また、このコードは、バックエンドのインフラストラクチャが別のユーザーからの不正アクセスから保護するものであると仮定しています。DataType
を指定していないため、UI に表示された際にデフォルトで表示状態になります。
public class User
{
[Required]
public int ID { get; set; }
public string Title { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime DateOfEmployment { get; set; }
[DataType(DataType.Currency)]
public decimal Salary { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
...
}
Example 1
のプロパティ Password
は属性 [DataType(DataType.Password)]
を指定していないため、UI に表示された際にデフォルトで非表示状態になりません。TextField
ウィジェットが、ユーザーが入力プロンプトに入力するパスワードを隠蔽しないことを示しています。
class SelectionContainerDisabledExampleApp extends StatelessWidget {
const SelectionContainerDisabledExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: "Please enter your password",
),
),
],
),
),
),
);
}
}
Example 1
での TextField
ウィジェットは、obscureText
プロパティを true
に設定せずにインスタンス化されたため、パスワードは「パスワードを入力してください」プロンプトで入力されたときに不明瞭化されません。PasswordCallback pc = new PasswordCallback("Please enter your password: ", true);
Example 1
での pc
は 2 番目のパラメーター onEcho
を true
にしてインスタンス化されたため、パスワードは「パスワードを入力してください」プロンプトで入力されたときに不明瞭化されません。
ViewController.h:
...
@property (nonatomic, retain) IBOutlet UITextField *passwordField;
...
ViewController.m:
...
NSString *password = _passwordField.text;
...
Example 1
にある passwordField
では secureTextEntry
プロパティが true
に設定されていないため、ユーザーがテキスト フィールドにパスワードを入力するときに、パスワードは不明瞭化されません。
...
@IBOutlet weak var passwordField: UITextField!
...
let password = passwordField.text
...
Example 1
にある passwordField
では secureTextEntry
プロパティが true
に設定されていないため、ユーザーがテキスト フィールドにパスワードを入力するときに、パスワードは不明瞭化されません。
...
tid = request->get_form_field( 'tid' ).
CALL TRANSACTION tid USING bdcdata MODE 'N'
MESSAGES INTO messtab.
...
APPHOME
を使用して、指定されたディレクトリからの相対パスに基づいてネイティブ ライブラリをロードします。
...
string lib = ConfigurationManager.AppSettings["APPHOME"];
Environment.ExitCode = AppDomain.CurrentDomain.ExecuteAssembly(lib);
...
LIBNAME
が含まれる別のパスを参照するようにアプリケーション構成プロパティ APPHOME
を変更することにより、ライブラリまたは実行可能ファイルをロードして、任意のコードをアプリケーションの上位権限で実行することを攻撃者に許可します。このプログラムは環境から読み取った値の検証を行わないので、システム プロパティ APPHOME
の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。
...
RegQueryValueEx(hkey, "APPHOME",
0, 0, (BYTE*)home, &size);
char* lib=(char*)malloc(strlen(home)+strlen(INITLIB));
if (lib) {
strcpy(lib,home);
strcat(lib,INITCMD);
LoadLibrary(lib);
}
...
INITLIB
を含む別のパスを参照させて任意のライブラリをロードし、アプリケーションの昇格権限を使ってライブラリのコードを実行できるようになっています。このプログラムでは環境から読み取った値の検証が実行されないため、攻撃者は APPHOME
の値を制御できれば、アプリケーションを操作して悪意のあるコードを実行させることができます。liberty.dll
という名前のライブラリを使用します。
LoadLibrary("liberty.dll");
liberty.dll
への絶対パスが指定されていません。攻撃者が liberty.dll
という名前を付けた悪意のあるライブラリを、目的のファイルより優先順位の高い検索場所に配置し、Web サーバー環境ではなく攻撃者の環境でプログラムを実行できる方法を確立すると、アプリケーションによって信頼されたファイルの代わりに悪意のあるライブラリがロードされます。こうしたアプリケーションのタイプは昇格した権限で実行されるため、攻撃者の liberty.dll
の内容は昇格した権限で実行され、攻撃者に完全なシステム制御の権限を与える可能性があります。LoadLibrary()
で使用される検索順によって可能になります。Windows の最近のバーションまで該当したことですが、現在のディレクトリがシステム ディレクトリより前に検索される場合は、攻撃者がローカルにプログラムを実行できても、このタイプの攻撃はそれほど影響はありません。検索順は使用オペレーティングシステムのバージョンによって異なりますが、新しいオペレーティングシステムでは次のレジストリキーの値によって制御されます。
HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
LoadLibrary()
は次のように動作します。SafeDllSearchMode
が 1 の場合、検索順序は次のようになります。PATH
環境変数にリストされているディレクトリ。SafeDllSearchMode
が 0 の場合、検索順序は次のようになります。PATH
環境変数にリストされているディレクトリ。
...
ACCEPT PROGNAME.
EXEC CICS
LINK PROGRAM(PROGNAME)
COMMAREA(COMA)
LENGTH(LENA)
DATALENGTH(LENI)
SYSID('CONX')
END-EXEC.
...
APPHOME
を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいてネイティブライブラリがロードされます。
...
String home = System.getProperty("APPHOME");
String lib = home + LIBNAME;
java.lang.Runtime.getRuntime().load(lib);
...
LIBNAME
が含まれている別のパスを参照するようにシステムプロパティ APPHOME
を変更することにより、攻撃者はライブラリをロードしてアプリケーションの任意のコマンドを昇格された権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME
の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。 System.loadLibrary()
を使用して、コードを library.dll
という名前のネイティブ ライブラリからロードします。このライブラリは通常、標準のシステムディレクトリにあります。
...
System.loadLibrary("library.dll");
...
System.loadLibrary()
がロードされるライブラリの、パスではなくライブラリ名を受け取ることです。Java 1.4.2 API マニュアルによると、この関数は次のように動作します [1]。library.dll
の悪意あるコピーを、アプリケーションがロードしようとするファイルより前の検索場所に配置することが可能な場合、アプリケーションは目的のファイルの代わりに悪意あるコピーをロードします。アプリケーションの性質上、このバイナリは昇格された権限で実行されます。つまり、攻撃者の library.dll
の内容もその昇格された権限で実行されるため、攻撃者はシステムを完全に制御してしまう可能性があります。Express
の「機能」を使用して動的にライブラリ ファイルをロードしています。Node.js
は、引き続き通常のライブラリ ロード パスでこのライブラリが含まれるファイルまたはディレクトリを検索します [1]。
var express = require('express');
var app = express();
app.get('/', function(req, res, next) {
res.render('tutorial/' + req.params.page);
});
Express
では、Response.render()
に渡されるページが、未知の拡張機能のライブラリがあればロードします。これは通常、"foo.pug" のような入力であれば問題ありません。これはよく知られたテンプレート エンジンである pug
ライブラリのロードを意味するためです。ただし、攻撃者がページを制御しているために拡張機能もその制御下にある場合、Node.js
モジュールのローディング パス内でライブラリをロードすることを選択できます。このプログラムでは URL パラメーターから受け取った情報が検証されないため、攻撃者はアプリケーションを操って悪意のあるコードを実行し、システムを制御できます。APPHOME
を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいてネイティブライブラリがロードされます。
...
$home = getenv("APPHOME");
$lib = $home + $LIBNAME;
dl($lib);
...
LIBNAME
が含まれている別のパスを参照するようにシステムプロパティ APPHOME
を変更することにより、攻撃者はライブラリをロードしてアプリケーションの任意のコマンドを昇格された権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME
の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。dl()
を使用して、sockets.dll
という名前のライブラリからコードをロードします。これは、インストールや構成に応じて、さまざまな場所からロードされる可能性があります。
...
dl("sockets");
...
dl()
がロードされるライブラリの、パスではなくライブラリ名を受け取ることです。sockets.dll
の悪意あるコピーを、アプリケーションがロードしようとするファイルより前の検索場所に配置することが可能な場合、アプリケーションは目的のファイルの代わりに悪意あるコピーをロードします。アプリケーションの性質上、このバイナリは昇格された権限で実行されます。つまり、攻撃者の sockets.dll
の内容もその昇格された権限で実行されるため、攻撃者はシステムを完全に制御してしまう可能性があります。Kernel.system()
を実行して、通常は標準システム ディレクトリ内にある program.exe
という実行可能プログラムを実行します。
...
system("program.exe")
...
Kernel.system()
は実行にシェルを使用します。攻撃者が環境変数 RUBYSHELL
または COMSPEC
を操作できる場合、変数から悪意のある実行可能プログラムを参照でき、それが Kernel.system()
へのコマンドでコールされる可能性があります。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の program.exe
もその権限で実行されるため、攻撃者はシステムを完全に制御してしまう可能性があります。Kernel.system()
のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH
変数を変更して、program.exe
という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の program.exe
もその権限で実行されるため、攻撃者はシステムを完全に制御してしまう可能性があります。Windows.Storage.ApplicationData
クラスの RoamingFolder
または RoamingSettings
プロパティを使用します。RoamingFolder
プロパティおよび RoamingSettings
プロパティは、ローミング アプリのデータストアのコンテナを取得します。このコンテナは、複数デバイス間でのデータの共有に使用することができます。ローミング アプリのデータストアに格納されているオブジェクトに対する読み書きにより、危険にさらされるリスクが高まります。その対象は、ローミング アプリのデータストアを使用してこれらのオブジェクトを共有するデータ、アプリケーション、およびシステムの機密性、完全性、および可用性です。null
であるかを確認する前に、null
の可能性があるポインタを間接参照する場合です。チェック後間接参照のエラーが発生するのは、プログラムが null
に対して明示的チェックを実行したにも関わらず、null
であることが判明しているポインタを間接参照した場合です。この種のエラーの多くは、タイプミスかプログラマの不注意が原因です。格納後間接参照のエラーは、プログラムが明示的にポインタを null
に設定し、後でそのポインタを間接参照した場合に発生します。このエラーは通常、変数の宣言時にプログラマがその変数を null
に初期化したことが原因で発生します。foo
が null
であることを確認してから、それを誤って間接参照しています。foo
が if
ステートメントでチェックされたときに null
になっていると、null
間接参照 が発生し、これが NULL ポインター例外の原因となります。例 2: 次のコードでは、プログラマは変数
if (foo is null) {
foo.SetBar(val);
...
}
foo
は null
ではないと仮定しており、オブジェクトを間接参照することによってこの仮定を確認しています。しかし、その後プログラマが foo
と null
を比較したときに、この仮定は成り立たなくなります。foo
が if
ステートメントでチェックされたときに null
であるとすれば、間接参照されたときにも null
である可能性があり、これが NULL ポインタ例外の原因となる場合があります。間接参照が安全でないか、後で実行するチェックが不要であるかのいずれかです。例 3: 次のコードでは、プログラマは明示的に変数
foo.SetBar(val);
...
if (foo is not null) {
...
}
foo
を null
に設定しています。続いて、オブジェクトの null
値をチェックする前に foo
を間接参照しています。
Foo foo = null;
...
foo.SetBar(val);
...
}
null
であるかを確認する前に、null
の可能性があるポインタを間接参照する場合です。チェック後間接参照のエラーが発生するのは、プログラムが null
に対して明示的チェックを実行したにも関わらず、null
であることが判明しているポインタを間接参照した場合です。この種のエラーの多くは、タイプミスかプログラマの不注意が原因です。格納後間接参照のエラーは、プログラムが明示的にポインタを null
に設定し、後でそのポインタを間接参照した場合に発生します。このエラーは通常、変数の宣言時にプログラマがその変数を null
に初期化したことが原因で発生します。ptr
は NULL
ではないと仮定してします。この仮定は、プログラマがポインタを間接参照したときに明らかになります。その後プログラマが ptr
と NULL
を比較したときに、この仮定は成り立たなくなります。ptr
が if
ステートメントでチェックされたときに NULL
であるとすれば、間接参照されたときにも NULL
である可能性があり、これがセグメンテーション違反の原因となる場合があります。例 2: 次のコードでは、プログラマは変数
ptr->field = val;
...
if (ptr != NULL) {
...
}
ptr
が NULL
であることを確認してから、続いてそれを誤って間接参照しています。ptr
が if
ステートメントでチェックされたときに NULL
になっていると、null
Dereference が発生し、これがセグメンテーション違反の原因となります。例 3: 次のコードでは、プログラマが文字列
if (ptr == null) {
ptr->field = val;
...
}
'\0'
(実際は 0) または NULL
を忘れたため、NULL ポインタを間接参照し、セグメンテーション違反を引き起こしています。例 4: 次のコードでは、プログラマは明示的に変数
if (ptr == '\0') {
*ptr = val;
...
}
ptr
を NULL
に設定しています。続いて、オブジェクトの null
値をチェックする前に ptr
を間接参照しています。
*ptr = NULL;
...
ptr->field = val;
...
}
null
に対して明示的チェックを実行したにも関わらず、null
であることが判明しているオブジェクトを間接参照した場合です。この種のエラーの多くは、タイプミスかプログラマの不注意が原因です。foo
が null
であることを確認してから、続いてそれを誤って間接参照しています。foo
が if
ステートメントでチェックされたときに null
になっていると、null
Dereference が発生し、これが NULL ポインタ例外の原因となります。
if (foo == null) {
foo.setBar(val);
...
}