response.sendRedirect("j_security_check?j_username="+usr+"&j_password="+pass);
...
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
puede leer el valor de password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
string value = regKey.GetValue(passKey).ToString());
byte[] decVal = Convert.FromBase64String(value);
NetworkCredential netCred =
new NetworkCredential(username,decVal.toString(),domain);
...
password
. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
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
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
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
puede leer el valor de la contraseña y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
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
podrá leer el valor de password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
Properties prop = new Properties();
prop.load(new FileInputStream("config.properties"));
String password = Base64.decode(prop.getProperty("password"));
DriverManager.getConnection(url, usr, password);
...
config.properties
puede leer el valor de password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
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
y la utiliza para descomprimir un archivo protegido con contraseña.
...
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
puede leer el valor de encoded_password
y determinar fácilmente que el valor se ha establecido con la codificación 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
puede leer el valor de password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
props = os.open('config.properties')
password = base64.b64decode(props[0])
link = MySQLdb.connect (host = "localhost",
user = "testuser",
passwd = password,
db = "test")
...
config.properties
puede leer el valor de password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
require 'pg'
require 'base64'
...
passwd = Base64.decode64(ENV['PASSWD64'])
...
conn = PG::Connection.new(:dbname => "myApp_production", :user => username, :password => passwd, :sslmode => 'require')
PASSWD64
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
...
val prop = new Properties();
prop.load(new FileInputStream("config.properties"));
val password = Base64.decode(prop.getProperty("password"));
DriverManager.getConnection(url, usr, password);
...
config.properties
puede leer el valor de password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.plist
y la utiliza para descomprimir un archivo protegido con contraseña.
...
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
puede leer el valor de encoded_password
y determinar fácilmente que el valor se ha establecido con la codificación 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
puede leer el valor de Password
y determinar fácilmente que el valor se ha establecido con la codificación base64. Un empleado malintencionado con acceso a esta información puede utilizarla para irrumpir en el sistema.
String password=request.getParameter("password");
...
DefaultUser user = (DefaultUser) ESAPI.authenticator().createUser(username, password, password);
...
*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
", la aplicación eliminará un archivo crítico e inmediatamente se bloqueará el sistema 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
" en lugar de una fecha válida, la aplicación revelará la configuración predeterminada de todos los parámetros del perfil de servidor de aplicaciones de SAP, lo que posiblemente conduciría a ataques más sofisticados.../../tomcat/conf/server.xml
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza la entrada desde un archivo de configuración para determinar qué archivo abrir y escribir en una consola de depuración o en un archivo de registro. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
", lo que hará que la aplicación elimine un archivo importante del sistema de Windows.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con privilegios adecuados y los usuarios malintencionados pueden modificar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión ".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
", que provocará que la aplicación elimine el archivo de configuración especificado.Ejemplo 2: el código siguiente utiliza entrada de la línea de comandos para determinar qué archivo abrir y reenviar al usuario. Si el programa se ejecuta con privilegios adecuados y los usuarios malintencionados pueden crear vínculos simbólicos al archivo, estos también pueden usar el programa para leer la primera parte de cualquier archivo del sistema.
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
", lo que hará que la aplicación elimine un archivo importante del sistema de 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
, no se valida headers.value('path')
antes de llevar a cabo las funciones de eliminación en archivos.../../tomcat/conf/server.xml
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: El siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y devolver al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos pueden utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
a la plataforma Android.
...
String rName = this.getIntent().getExtras().getString("reportName");
File rFile = getBaseContext().getFileStreamPath(rName);
...
rFile.delete();
...
../../tomcat/conf/server.xml
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el código siguiente utiliza entrada del almacenamiento local para determinar qué archivo abrir y devolver al usuario. Si los usuarios maliciosos pueden cambiar el contenido del almacenamiento local, pueden utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
...
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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: El siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y devolver al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos pueden utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
a la plataforma Android.
...
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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
$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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
", lo que podría causar que la aplicación eliminase uno de sus propios archivos de configuración.Ejemplo 2: el siguiente código utiliza una entrada de un archivo de configuración para determinar el archivo que se debe abrir y reenviar al usuario. Si el programa se ejecuta con los privilegios adecuados y los usuarios malintencionados pueden cambiar el archivo de configuración, estos podrán utilizar el programa para leer cualquier archivo del sistema que termine con la extensión
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
...
...
" 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
, no se valida p_ifile
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo ZIP se encontró originalmente en el directorio "/tmp/
" de un equipo basado en Unix, una entrada ZIP era "../etc/hosts
" y la aplicación se ejecutó con los permisos necesarios, se sobrescribe el archivo hosts
del sistema. A su vez, esto permite que el tráfico del equipo vaya donde el usuario malintencionado desea, por ejemplo, a su propio equipo.
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
, no se valida entry.FullName
antes de llevar a cabo las operaciones de lectura/escritura en los datos de la entrada. Si el archivo zip se colocase originalmente en el directorio "C:\TEMP
", un nombre de entrada de zip incluyera "segmentos ..\
" y la aplicación se ejecutase con los permisos necesarios, dicho archivo podría sobrescribir de forma arbitraria algunos archivos de sistema.
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
, no se valida f.Name
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo zip se encontrase originalmente en el directorio "/tmp/
" de un equipo basado en Unix, una entrada zip fuese "../etc/hosts
" y la aplicación se ejecutase con los permisos necesarios, se sobrescribiría el archivo hosts
del sistema. A su vez, esto permitiría que el tráfico del equipo fuese donde el usuario malintencionado desease, por ejemplo, a su propio equipo.
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
, no se valida zipEntry.getName()
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo zip se encontrase originalmente en el directorio "/tmp/
" de un equipo basado en Unix, una entrada zip fuese "../etc/hosts
" y la aplicación se ejecutase con los permisos necesarios, se sobrescribiría el archivo hosts
del sistema. A su vez, esto permitiría que el tráfico del equipo fuese donde el usuario malintencionado desease, por ejemplo, a su propio equipo.
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
, no se valida entry.fileName
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo zip se encontrase originalmente en el directorio "Documents/hot_patches
" de una aplicación iOS, y una entrada ZIP fuese "../js/page.js
", dicho archivo podría sobrescribir el archivo page.js
. Esto, a su vez, permitiría al atacante inyectar código malicioso que podría dar lugar a la ejecución de código.
...
$zip = new ZipArchive();
$zip->open("userdefined.zip", ZipArchive::RDONLY);
$zpm = $zip->getNameIndex(0);
$zip->extractTo($zpm);
...
Example 1
, no se valida f.Name
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo zip se encuentra en el directorio "/tmp/
" de un equipo basado en Unix, una entrada ZIP es "../etc/hosts
" y la aplicación se ejecuta con los permisos necesarios, se sobrescribirá el archivo hosts
del sistema. Esto permite que el tráfico del equipo vaya donde el usuario malintencionado desea, por ejemplo, a su propio equipo.
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()
Ejemplo 2: El siguiente ejemplo extrae archivos de un archivo zip y los escribe en el disco de forma insegura.
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
, no se valida entry.getName
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo zip se encontrase originalmente en el directorio "/tmp/
" de un equipo basado en Unix, una entrada zip fuese "../etc/hosts
" y la aplicación se ejecutase con los permisos necesarios, se sobrescribiría el archivo hosts
del sistema. A su vez, esto permitiría que el tráfico del equipo fuese donde el usuario malintencionado desease, por ejemplo, a su propio equipo.
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
, no se valida entry.fileName
antes de llevar a cabo las funciones de lectura/escritura en los datos de la entrada. Si el archivo zip se encontrase originalmente en el directorio "Documents/hot_patches
" de una aplicación iOS, y una entrada ZIP fuese "../js/page.js
", dicho archivo podría sobrescribir el archivo page.js
. Esto, a su vez, permitiría al atacante inyectar código malicioso que podría dar lugar a la ejecución de código.
pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
Example 1
registra una contraseña de texto sin formato en el sistema de archivos. Aunque muchos desarrolladores confían en el sistema de archivos como una ubicación segura de almacenamiento para los datos, el usuario no debería confiar absolutamente, en especial, cuando la privacidad es una preocupación.
...
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
recibirá el mensaje. La difusión ni siquiera está protegida con un permiso para limitar el número de destinatarios, aunque en este caso no recomendamos el uso de permisos como solución.doExchange()
.
try {
doExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
, el programa continuaría ejecutándose como si no hubiera ocurrido nada inusual. El programa no registra ninguna evidencia que aluda a la situación especial, lo que podría frustrar cualquier intento posterior de explicar el comportamiento del programa.DoExchange()
.
try {
DoExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
se fuese a iniciar en algún momento, el programa seguiría ejecutándose como si no hubiese ocurrido nada inusual. El programa no registrará ninguna prueba que indique la situación especial, evitando potencialmente cualquier intento posterior de explicar el comportamiento del programa.doExchange()
.
try {
doExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
se fuese a iniciar en algún momento, el programa seguiría ejecutándose como si no hubiese ocurrido nada inusual. El programa no registrará ninguna prueba que indique la situación especial, evitando potencialmente cualquier intento posterior de explicar el comportamiento del programa.doExchange()
.
try {
doExchange();
}
catch (exception $e) {
// this can never happen
}
RareException
se fuese a iniciar en algún momento, el programa seguiría ejecutándose como si no hubiese ocurrido nada inusual. El programa no registrará ninguna prueba que indique la situación especial, evitando potencialmente cualquier intento posterior de explicar el comportamiento del programa.open()
.
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except:
# This will never happen
pass
RareException
se fuese a iniciar en algún momento, el programa seguiría ejecutándose como si no hubiese ocurrido nada inusual. El programa no registrará ninguna prueba que indique la situación especial, evitando potencialmente cualquier intento posterior de explicar el comportamiento del programa.Exception
, se pueden ocultar excepciones que requieran un tratamiento especial o que no se deberían obtener en este punto del programa. Si se obtiene una excepción demasiado amplia, básicamente hace fracasar el propósito de las excepciones tipificadas de .NET, y puede resultar particularmente peligroso si el programa se desarrolla y comienza a iniciar nuevos tipos de excepciones. Los nuevos tipos de excepciones quedarán desatendidas.
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()
para iniciar un nuevo tipo de excepción que debería tratarse de forma diferente, el amplio bloque catch evitará que el compilador señale la situación. Además, ahora el bloque catch nuevo tratará también excepciones de los tipos ApplicationException
y NullReferenceException
, lo cual no es el propósito del programador.Exception
, se pueden ocultar excepciones que requieran un tratamiento especial o que no se deberían obtener en este punto del programa. Si se obtiene una excepción demasiado amplia, básicamente hace fracasar el propósito de las excepciones tipificadas de Java, y puede resultar particularmente peligroso si el programa se desarrolla y comienza a iniciar nuevos tipos de excepciones. Los nuevos tipos de excepciones quedarán desatendidas.
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()
para iniciar un nuevo tipo de excepción que debería tratarse de forma diferente, el amplio bloque catch evitará que el compilador señale la situación. Es más, el nuevo bloque de filtrado ahora también administra las excepciones derivadas de RuntimeException
como ClassCastException
y NullPointerException
, que no es el propósito del programador.Exception
o Throwable
dificulta a los autores de llamada hacer un buen trabajo en cuanto al tratamiento y la recuperación de errores. El mecanismo de excepciones de Java se ha configurado para facilitar a los autores de llamada la anticipación de qué puede salir mal y escribir código para administrar cada circunstancia de excepción específica. Declarar que un método lance una forma genérica de excepción frustra este sistema.
public void doExchange()
throws IOException, InvocationTargetException,
SQLException {
...
}
public void doExchange()
throws Exception {
...
}
doExchange()
introduce un nuevo tipo de excepción que debería tratarse de forma diferente a las excepciones anteriores, no hay una forma fácil de exigir este requisito.NullPointerException
.NullPointerException
bajo tres circunstancias:NullPointerException
para señalar una condición de error.NullPointerException
.
try {
mysteryMethod();
}
catch (NullPointerException npe) {
}
finally
provocará que las excepciones se pierdan.finally
provocará que todas las excepciones que se puedan lanzar en el bloque try se descarten.MagicException
lanzada por la segunda llamada para doMagic
con true
transferido a ella nunca se entregará al autor de llamada. La instrucción return dentro del bloque finally
provocará que la excepción se descarte.
public class MagicTrick {
public static class MagicException extends Exception { }
public static void main(String[] args) {
System.out.println("Watch as this magical code makes an " +
"exception disappear before your very eyes!");
System.out.println("First, the kind of exception handling " +
"you're used to:");
try {
doMagic(false);
} catch (MagicException e) {
// An exception will be caught here
e.printStackTrace();
}
System.out.println("Now, the magic:");
try {
doMagic(true);
} catch (MagicException e) {
// No exception caught here, the finally block ate it
e.printStackTrace();
}
System.out.println("tada!");
}
public static void doMagic(boolean returnFromFinally)
throws MagicException {
try {
throw new MagicException();
}
finally {
if (returnFromFinally) {
return;
}
}
}
}
finally
provocará que las excepciones se pierdan.finally
provocará que todas las excepciones que se puedan lanzar en el bloque try se descarten.exception
lanzada por la segunda llamada para doMagic
con True
transferido a ella nunca se entregará al autor de llamada. La instrucción RETURN dentro del bloque finally
provocará que la excepción se descarte."disappear before your very eyes!" . PHP_EOL;
echo "First, the kind of exception handling " .
"you're used to:" . PHP_EOL;
try {
doMagic(False);
} catch (exception $e) {
// An exception will be caught here
echo $e->getMessage();
}
echo "Now, the magic:" . PHP_EOL;
try {
doMagic(True);
} catch (exception $e) {
// No exception caught here, the finally block ate it
echo $e->getMessage();
}
echo "Tada!" . PHP_EOL;
function doMagic($returnFromFinally) {
try {
throw new Exception("Magic Exception" . PHP_EOL);
}
finally {
if ($returnFromFinally) {
return;
}
}
}
?>
ThreadDeath
no se vuelve a lanzar, el subproceso en cuestión podría no acabar.ThreadDeath
solo deben filtrarse si una aplicación tiene que limpiar después de finalizar de forma asíncrona. Si se filtra un error ThreadDeath
, es importante que se vuelva a lanzar para que el subproceso finalice realmente. El propósito de lanzar ThreadDeath
es detener un subproceso. Si ThreadDeath
es absorbido, puede impedir que un subproceso se detenga y dé lugar a un comportamiento inesperado, puesto que quien haya lanzado originalmente ThreadDeath
espera que el subproceso se detenga.ThreadDeath
, pero no lo vuelve a lanzar.
try
{
//some code
}
catch(ThreadDeath td)
{
//clean up code
}
throw
dentro de un bloque finally
rompe la progresión lógica de try-catch-finally
.finally
siempre se ejecutan después de su bloque try-catch
correspondiente y se utilizan frecuentemente para liberar recursos asignados, como controladores de archivos o cursores de base de datos. Lanzar una excepción en un bloque finally
puede derivar el código de limpieza crítico, puesto que la ejecución normal del programa se interrumpirá. stmt.close()
se deriva cuando se lanza la FileNotFoundException
.
public void processTransaction(Connection conn) throws FileNotFoundException
{
FileInputStream fis = null;
Statement stmt = null;
try
{
stmt = conn.createStatement();
fis = new FileInputStream("badFile.txt");
...
}
catch (FileNotFoundException fe)
{
log("File not found.");
}
catch (SQLException se)
{
//handle error
}
finally
{
if (fis == null)
{
throw new FileNotFoundException();
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (SQLException e)
{
log(e);
}
}
}
}
javax.net.ssl.SSLHandshakeException
, javax.net.ssl.SSLKeyException
y javax.net.ssl.SSLPeerUnverifiedException
transmiten errores importantes relacionados con una conexión SSL. Si estos errores no se administran explícitamente, la conexión puede dejarse en un estado inesperado y potencialmente inseguro.
private final Logger logger =
Logger.getLogger(MyClass.class);
public class MyClass {
private final static Logger good =
Logger.getLogger(MyClass.class);
private final static Logger bad =
Logger.getLogger(MyClass.class);
private final static Logger ugly =
Logger.getLogger(MyClass.class);
...
}
Console.Out
o Console.Error
en lugar de una interfaz de registro dedicada, es difícil supervisar el comportamiento del programa.
public class MyClass {
...
Console.WriteLine("hello world");
...
}
Console.WriteLine()
.Console.WriteLine
podría indicar un descuido en el paso a un sistema de registro estructurado.os.Stdout
o os.Stderr
en lugar de una interfaz de registro dedicada, es difícil supervisar el comportamiento del programa.
...
func foo(){
fmt.Println("Hello World")
}
fmt.Println()
.os.Stdout
o os.Stderr
puede indicar un descuido en el paso a un sistema estructurado de registro.System.out
o System.err
en lugar de una interfaz de registro dedicada, es difícil supervisar el comportamiento del programa.
public class MyClass
...
System.out.println("hello world");
...
}
System.out.println()
.System.out
o System.err
podría indicar un descuido en el paso a un sistema estructurado de registro.process.stdout
o process.stderr
en lugar de una interfaz de registro dedicada, resulta más difícil supervisar el comportamiento del programa.
process.stdin.on('readable', function(){
var s = process.stdin.read();
if (s != null){
process.stdout.write(s);
}
});
process.stdout.write()
.process.stdout
o process.stderr
podría indicar un descuido en el paso a un sistema estructurado de registro.print
o println
en lugar de una interfaz de registro dedicada, es difícil supervisar el comportamiento del programa.
class MyClass {
...
println("hello world")
...
}
}
print
o println
.
sys.stdout.write("hola, mundo")
sys.stdout
o sys.stderr
podría indicar un descuido en el paso a un sistema estructurado de registro.Kernel.puts
,Kernel.warn
o Kernel.printf
en lugar de una interfaz de registro dedicada, resulta más difícil supervisar el comportamiento del programa.
...
puts "hello world"
...
Kernel.puts
.Kernel.puts
,Kernel.warn
o Kernel.printf
podría indicar un descuido en el paso a un sistema estructurado de registro.Logger
, pero registra información en un flujo de salida del sistema:
require 'logger'
...
logger = Logger.new($stdout)
logger.info("hello world")
...
public class Totaller {
private int total;
public int total() {
...
}
}
synchronized(this) { }
finalize()
solo debe ser llamado por el JVM después de que el objeto haya sido recolectado.finalize()
de objeto sea llamado desde fuera del finalizador, se trata de una mala idea. Por ejemplo, llamar finalize()
explícitamente indica que finalize()
se llamará más de una vez: la primera vez será la llamada explícita y la última vez será la llamada que se hace después de que el objeto sea recolectado.finalize()
explícitamente:
// time to clean up
widget.finalize();