remove
para excluir todo o conjunto de dados. Recentemente, tem havido relatos de ataques mal-intencionados em instâncias desprotegidas do MongoDB abertamente em execução na Internet. O atacante apagou o banco de dados e exigiu que um resgate fosse pago para que ele pudesse ser restaurado.remove
para excluir todo o conjunto de dados. Recentemente, tem havido relatos de ataques mal-intencionados em instâncias desprotegidas do MongoDB abertamente em execução na Internet. O atacante apagou o banco de dados e exigiu que um resgate fosse pago para que ele pudesse ser restaurado.FLUSHALL
pode ser usado por um invasor externo para excluir todo o conjunto de dados. Recentemente, tem havido relatos de ataques mal-intencionados em instâncias desprotegidas do Redis abertamente em execução na Internet. O atacante apagou o banco de dados e exigiu que um resgate fosse pago para que ele pudesse ser restaurado. Read()
e os métodos relacionados que fazem parte de várias classes System.IO
. A maioria dos erros e eventos incomuns no .NET é resultante do lançamento de uma exceção. (Esta é uma das vantagens de .NET em relação a linguagens como a C: Exceções facilitam para os programadores refletirem sobre o que pode dar errado.) Porém, as classes de fluxo e leitor não consideram incomum nem excepcional quando apenas uma pequena quantidade de dados torna-se disponível. Essas classes simplesmente adicionam a pequena quantidade de dados ao buffer de retorno e definem o valor de retorno como o número de bytes ou caracteres lidos. Não há garantia de que a quantidade de dados retornados seja igual à quantidade de dados solicitados.Read()
e outros métodos de E/S e garantam o recebimento da quantidade de dados esperada.Read()
. Se um invasor puder criar um arquivo menor, o programa reciclará o restante dos dados do usuário anterior e lidará com eles como se pertencessem ao invasor.
char[] byteArray = new char[1024];
for (IEnumerator i=users.GetEnumerator(); i.MoveNext() ;i.Current()) {
string userName = (string) i.Current();
string pFileName = PFILE_ROOT + "/" + userName;
StreamReader sr = new StreamReader(pFileName);
sr.Read(byteArray,0,1024);//the file is always 1k bytes
sr.Close();
processPFile(userName, byteArray);
}
char buf[10], cp_buf[10];
fgets(buf, 10, stdin);
strcpy(cp_buf, buf);
fgets()
for retornado, buf
conterá uma cadeia de caracteres com terminação nula de comprimento 9 ou menor. Porém, se um erro de E/S ocorrer, fgets()
não estabelecerá uma terminação nula para buf
. Além disso, se o final do arquivo for atingido antes que todos os caracteres sejam lidos, fgets()
será retornado sem gravar nada em buf
. Em ambas as situações, fgets()
sinaliza que algo inusitado aconteceu retornando NULL
, mas, nesse código, o aviso não será percebido. A falta de um terminador nulo em buf
pode resultar em um estouro de buffer na chamada subsequente para strcpy()
.read()
e os métodos relacionados que fazem parte de várias classes java.io
. A maioria dos erros e eventos incomuns em Java é resultante do lançamento de uma exceção. (Esta é uma das vantagens de Java em relação a linguagens como a C: Exceções facilitam para os programadores refletirem sobre o que pode dar errado.) Porém, as classes de fluxo e leitor não consideram incomum nem excepcional quando apenas uma pequena quantidade de dados torna-se disponível. Essas classes simplesmente adicionam a pequena quantidade de dados ao buffer de retorno e definem o valor de retorno como o número de bytes ou caracteres lidos. Não há garantia de que a quantidade de dados retornados seja igual à quantidade de dados solicitados.read()
e outros métodos de E/S para garantir o recebimento da quantidade de dados esperada.read()
. Se um invasor puder criar um arquivo menor, o programa reciclará o restante dos dados do usuário anterior e lidará com eles como se pertencessem ao invasor.
FileInputStream fis;
byte[] byteArray = new byte[1024];
for (Iterator i=users.iterator(); i.hasNext();) {
String userName = (String) i.next();
String pFileName = PFILE_ROOT + "/" + userName;
FileInputStream fis = new FileInputStream(pFileName);
fis.read(byteArray); // the file is always 1k bytes
fis.close();
processPFile(userName, byteArray);
}
read()
. Se um invasor puder criar um arquivo menor, o programa reciclará o restante dos dados do usuário anterior e lidará com eles como se pertencessem ao invasor.
var fis: FileInputStream
val byteArray = ByteArray(1023)
val i: Iterator<*> = users.iterator()
while (i.hasNext()) {
val userName = i.next() as String
val pFileName: String = PFILE_ROOT.toString() + "/" + userName
val fis = FileInputStream(pFileName)
fis.read(byteArray) // the file is always 0k bytes
fis.close()
processPFile(userName, byteArray)
}
Finalize()
para StreamReader
chama Close()
eventualmente, mas não há nenhuma garantia de quanto tempo será necessário antes que o método Finalize()
seja invocado. Na verdade, não há nenhuma garantia de que Finalize()
nunca será invocado. Em um ambiente muito ativo, isso pode fazer com que a VM use todos os seus identificadores de arquivo disponíveis.Exemplo 2: Em condições normais, o código a seguir executa uma consulta de banco de dados, processa os resultados retornados pelo banco de dados e fecha o objeto
private void processFile(string fName) {
StreamWriter sw = new StreamWriter(fName);
string line;
while ((line = sr.ReadLine()) != null)
processLine(line);
}
SqlConnection
alocado. Porém, se ocorrer uma exceção durante a execução do SQL ou o processamento dos resultados, o objeto SqlConnection
não será fechado. Se isso acontecer com frequência suficiente, o banco de dados ficará sem cursores disponíveis e não poderá executar mais consultas SQL.
...
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(queryString);
cmd.Connection = conn;
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
HarvestResults(rdr);
conn.Connection.Close();
...
int decodeFile(char* fName)
{
char buf[BUF_SZ];
FILE* f = fopen(fName, "r");
if (!f) {
printf("cannot open %s\n", fName);
return DECODE_FAIL;
} else {
while (fgets(buf, BUF_SZ, f)) {
if (!checkChecksum(buf)) {
return DECODE_FAIL;
} else {
decodeBlock(buf);
}
}
}
fclose(f);
return DECODE_SUCCESS;
}
CALL "CBL_CREATE_FILE"
USING filename
access-mode
deny-mode
device
file-handle
END-CALL
IF return-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
PERFORM write-data
IF ws-status-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
DISPLAY "Success!"
END-IF
END-IF
CALL "CBL_CLOSE_FILE"
USING file-handle
END-CALL
GOBACK
.
New()
estabelece uma nova conexão com o daemon de log do sistema. Faz parte do pacote log.syslog. Cada gravação para o gravador retornado envia uma mensagem de log com a prioridade fornecida (uma combinação do recurso e gravidade do syslog) e a tag de prefixo. Em um ambiente ocupado, isso pode fazer com que o sistema use todos os seus soquetes.Exemplo 2: Nesse exemplo, o método
func TestNew() {
s, err := New(syslog.LOG_INFO|syslog.LOG_USER, "the_tag")
if err != nil {
if err.Error() == "Unix syslog delivery error" {
fmt.Println("skipping: syslogd not running")
}
fmt.Println("New() failed: %s", err)
}
}
Dial()
do pacote net/smtp
retorna um novo cliente conectado a um servidor SMTP no localhost. Os recursos de conexão são alocados, mas nunca são liberados chamando a função Close()
.
func testDial() {
client, _ := smtp.Dial("127.0.0.1")
client.Hello("")
}
Arena.ofConfined()
não está fechado.
...
Arena offHeap = Arena.ofConfined()
MemorySegment str = offHeap.allocateUtf8String("data");
...
//offHeap is never closed
BEGIN
...
F1 := UTL_FILE.FOPEN('user_dir','u12345.tmp','R',256);
UTL_FILE.GET_LINE(F1,V1,32767);
...
END;
Camera
em seus manipuladores de eventos onPause()
, onStop()
ou onDestroy()
.Camera
que não é liberada em um retorno de chamada onPause()
, onStop()
ou onDestroy()
. O sistema operacional Android invoca esses retornos de chamada sempre que precisa enviar a atividade atual para segundo plano ou quando precisa destruir a atividade temporariamente nos casos em que o sistema está com poucos recursos. Ao não liberar o objeto Camera
corretamente, a atividade impede que outros aplicativos (ou até mesmo instâncias futuras do mesmo aplicativo) acessem a câmara. Além disso, manter a posse da instância de Camera
enquanto a atividade está pausada pode afetar negativamente a experiência do usuário por meio do esgotamento desnecessário da bateria.onPause()
base, que deve ser usado para liberar o objeto Camera
, nem o libera corretamente durante sua sequência de desligamento.
public class UnreleasedCameraActivity extends Activity {
private Camera cam;
@Override
public void onCreate(Bundle state) {
...
}
@Override
public void onRestart() {
...
}
@Override
public void onStop() {
cam.stopPreview();
}
}
MediaRecorder
, MediaPlayer
ou AudioRecord
em seus manipuladores de eventos onPause()
, onStop()
ou onDestroy()
.onPause()
, onStop()
ou onDestroy()
. O sistema operacional Android invoca esses retornos de chamada sempre que precisa enviar a atividade atual para segundo plano ou quando precisa destruir a atividade temporariamente nos casos em que o sistema está com poucos recursos. Ao não liberar o objeto de mídia corretamente, a atividade faz com que acessos subsequentes ao hardware de mídia do Android (por outros aplicativos ou até mesmo pelo mesmo aplicativo) retrocedam para as implementações de software ou até mesmo falhem completamente. Deixar abertas muitas instâncias de mídia não liberadas pode fazer com que o Android lance exceções, causando efetivamente uma negação de serviço. Além disso, manter a posse da instância de mídia enquanto a atividade está pausada pode afetar negativamente a experiência do usuário por meio do esgotamento desnecessário da bateria.onPause()
base, que deve ser usado para liberar o objeto de mídia, nem o libera corretamente durante sua sequência de desligamento.
public class UnreleasedMediaActivity extends Activity {
private MediaPlayer mp;
@Override
public void onCreate(Bundle state) {
...
}
@Override
public void onRestart() {
...
}
@Override
public void onStop() {
mp.stop();
}
}
onPause()
, onStop()
ou onDestroy()
.onPause()
, onStop()
ou onDestroy()
. O sistema operacional Android invoca esses retornos de chamada sempre que precisa enviar a atividade atual para segundo plano ou quando precisa destruir a atividade temporariamente nos casos em que o sistema está com poucos recursos. Ao não fechar o banco de dados corretamente, a atividade poderá esgotar cursores disponíveis do dispositivo se for reiniciada constantemente. Além disso, dependendo da implementação, o sistema operacional Android também pode lançar DatabaseObjectNotClosedException
, que travará o aplicativo se a exceção não for detectada.onPause()
base, que deve ser usado para liberar o objeto de banco de dados, nem o libera corretamente durante sua sequência de desligamento.
public class MyDBHelper extends SQLiteOpenHelper {
...
}
public class UnreleasedDBActivity extends Activity {
private myDBHelper dbHelper;
private SQLiteDatabase db;
@Override
public void onCreate(Bundle state) {
...
db = dbHelper.getWritableDatabase();
...
}
@Override
public void onRestart() {
...
}
@Override
public void onStop() {
db.insert(cached_data); // flush cached data
}
}
DATA: result TYPE demo_update,
request TYPE REF TO IF_HTTP_REQUEST,
obj TYPE REF TO CL_SQL_CONNECTION.
TRY.
...
obj = cl_sql_connection=>get_connection( `R/3*my_conn`).
FINAL(sql) = NEW cl_sql_prepared_statement(
statement = `INSERT INTO demo_update VALUES( ?, ?, ?, ?, ?, ? )`).
CATCH cx_sql_exception INTO FINAL(exc).
...
ENDTRY.
SqlConnection
alocado. Mas, se ocorrer uma exceção durante a execução do SQL ou o processamento dos resultados, o objeto SqlConnection
não será fechado. Se isso acontecer com frequência suficiente, o banco de dados ficará sem cursores disponíveis e não poderá executar mais consultas SQL.
...
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(queryString);
cmd.Connection = conn;
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
HarvestResults(rdr);
conn.Connection.Close();
...
- void insertUser:(NSString *)name {
...
sqlite3_stmt *insertStatement = nil;
NSString *insertSQL = [NSString stringWithFormat:@INSERT INTO users (name, age) VALUES (?, ?)];
const char *insert_stmt = [insertSQL UTF8String];
...
if ((result = sqlite3_prepare_v2(database, insert_stmt,-1, &insertStatement, NULL)) != SQLITE_OK) {
MyLog(@"%s: sqlite3_prepare error: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), result);
return;
}
if ((result = sqlite3_step(insertStatement)) != SQLITE_DONE) {
MyLog(@"%s: step error: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), result);
return;
}
...
}
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(CXN_SQL);
harvestResults(rs);
stmt.close();
func insertUser(name:String, age:int) {
let dbPath = URL(fileURLWithPath: Bundle.main.resourcePath ?? "").appendingPathComponent("test.sqlite").absoluteString
var db: OpaquePointer?
var stmt: OpaquePointer?
if sqlite3_open(dbPath, &db) != SQLITE_OK {
print("Error opening articles database.")
return
}
let queryString = "INSERT INTO users (name, age) VALUES (?,?)"
if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
let errmsg = String(cString: sqlite3_errmsg(db)!)
log("error preparing insert: \(errmsg)")
return
}
if sqlite3_bind_text(stmt, 1, name, -1, nil) != SQLITE_OK{
let errmsg = String(cString: sqlite3_errmsg(db)!)
log("failure binding name: \(errmsg)")
return
}
if sqlite3_bind_int(stmt, 2, age) != SQLITE_OK{
let errmsg = String(cString: sqlite3_errmsg(db)!)
log("failure binding name: \(errmsg)")
return
}
if sqlite3_step(stmt) != SQLITE_DONE {
let errmsg = String(cString: sqlite3_errmsg(db)!)
log("failure inserting user: \(errmsg)")
return
}
}
finalize()
para ZipFile
chama close()
por fim, mas não há nenhuma garantia de quanto tempo será necessário antes que o método finalize()
seja invocado. Em um ambiente muito ativo, isso pode fazer com que a JVM use todos os seus identificadores de arquivo.Exemplo 2: Em condições normais, a seguinte correção fecha corretamente o identificador de arquivo após a impressão de todas as entradas do arquivo zip. Porém, se uma exceção ocorrer durante a iteração através das entradas, o identificador de arquivo zip não será fechado. Se isso acontece com bastante frequência, a JVM ainda poderá ficar sem identificadores de arquivos disponíveis.
public void printZipContents(String fName) throws ZipException, IOException, SecurityException, IllegalStateException, NoSuchElementException {
ZipFile zf = new ZipFile(fName);
Enumeration<ZipEntry> e = zf.entries();
while (e.hasMoreElements()) {
printFileInfo(e.nextElement());
}
}
public void printZipContents(String fName) throws ZipException, IOException, SecurityException, IllegalStateException, NoSuchElementException {
ZipFile zf = new ZipFile(fName);
Enumeration<ZipEntry> e = zf.entries();
while (e.hasMoreElements()) {
printFileInfo(e.nextElement());
}
zf.close();
}
...
lo_client = cl_apc_tcp_client_manager=>create( i_host = host
i_port = port
i_frame = lv_frame
i_protocol = protocol
i_ssl_id = ssl_id
i_event_handler = lo_event_handler ).
" initiate the connection setup, successful connect leads to execution of ON_OPEN
lo_client->connect( ).
...
Exemplo 2: Em condições normais, a correção a seguir fecha corretamente o soquete e quaisquer fluxos associados. Porém, se ocorrer uma exceção durante a leitura da entrada ou a gravação dos dados no fluxo, o objeto de soquete não será fechado. Se isso acontecer com frequência suficiente, o sistema ficará sem soquetes e não poderá lidar com mais conexões.
private void echoSocket(String host, int port) throws UnknownHostException, SocketException, IOException
{
Socket sock = new Socket(host, port);
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
while ((String socketData = reader.readLine()) != null) {
System.out.println(socketData);
}
}
private void echoSocket(String host, int port) throws UnknownHostException, SocketException, IOException
{
Socket sock = new Socket(host, port);
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
while ((String socketData = reader.readLine()) != null) {
System.out.println(socketData);
}
sock.close();
}
Finalize()
para StreamReader
eventualmente chama Close()
, mas não há garantia de quanto tempo levará até que o método Finalize()
seja invocado. Na verdade, não há nenhuma garantia de que Finalize()
nunca será invocado. Em um ambiente muito ativo, isso pode fazer com que a VM use todos os seus identificadores de arquivo disponíveis.
private void processFile(string fName) {
StreamWriter sw = new StreamWriter(fName);
string line;
while ((line = sr.ReadLine()) != null)
processLine(line);
}
finalize()
para FileInputStream
eventualmente chama close()
, mas não há garantia de quanto tempo levará até que o método finalize()
será invocado. Em um ambiente muito ativo, isso pode fazer com que a JVM use todos os seus identificadores de arquivo.
private void processFile(String fName) throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream(fName);
int sz;
byte[] byteArray = new byte[BLOCK_SIZE];
while ((sz = fis.read(byteArray)) != -1) {
processBytes(byteArray, sz);
}
}
...
CFIndex numBytes;
do {
UInt8 buf[bufferSize];
numBytes = CFReadStreamRead(readStream, buf, sizeof(buf));
if( numBytes > 0 ) {
handleBytes(buf, numBytes);
} else if( numBytes < 0 ) {
CFStreamError error = CFReadStreamGetError(readStream);
reportError(error);
}
} while( numBytes > 0 );
...
def readFile(filename: String): Unit = {
val data = Source.fromFile(fileName).getLines.mkString
// Use the data
}
...
func leak(reading input: InputStream) {
input.open()
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
while input.hasBytesAvailable {
let read = input.read(buffer, maxLength: bufferSize)
}
buffer.deallocate(capacity: bufferSize)
}
...
performOperationInCriticalSection()
, mas não consegue liberá-lo quando uma exceção é lançada nesse método.
Object synchronizationObject = new Object ();
System.Threading.Monitor.Enter(synchronizationObject);
performOperationInCriticalSection();
System.Threading.Monitor.Exit(synchronizationObject);
int helper(char* fName)
{
int status;
...
pthread_cond_init (&count_threshold_cv, NULL);
pthread_mutex_init(&count_mutex, NULL);
status = perform_operation();
if (status) {
printf("%s", "cannot perform operation");
return OPERATION_FAIL;
}
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
return OPERATION_SUCCESS;
}
CALL "CBL_GET_RECORD_LOCK"
USING file-handle
record-offset
record-length
reserved
END-CALL
IF return-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
PERFORM write-data
IF ws-status-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
DISPLAY "Success!"
END-IF
END-IF
CALL "CBL_FREE_RECORD_LOCK"
USING file-handle
record-offset
record-length
reserved
END-CALL
GOBACK
.
performOperationInCriticalSection()
, mas não consegue liberá-lo quando uma exceção é lançada nesse método.
ReentrantLock myLock = new ReentrantLock ();
myLock.lock();
performOperationInCriticalSection();
myLock.unlock();
performOperationInCriticalSection()
, mas nunca o libera.
os_unfair_lock lock1 = OS_UNFAIR_LOCK_INIT;
os_unfair_lock_lock(&lock1);
performOperationInCriticalSection();
performOperationInCriticalSection()
, mas nunca o libera.
let lock1 = OSAllocatedUnfairLock()
lock1.lock()
performOperationInCriticalSection();
Echo
. A classe declara um método nativo que usa C para ecoar comandos inseridos no console de volta para o usuário.
class Echo {
public native void runEcho();
static {
System.loadLibrary("echo");
}
public static void main(String[] args) {
new Echo().runEcho();
}
}
Echo
:
#include <jni.h>
#include "Echo.h" //a classe java doExample 1
compilada com javah
#include <stdio.h>
JNIEXPORT void JNICALL
Java_Echo_runEcho(JNIEnv *env, jobject obj)
{
char buf[64];
gets(buf);
printf(buf);
}
gets()
, que não realiza nenhuma verificação de limites em sua entrada.Example 1
pode ser facilmente detectada por meio de uma auditoria de código-fonte da implementação do método nativo. Isso pode não ser prático ou possível, dependendo da disponibilidade do código-fonte C e de como o projeto está estruturado, mas, em muitos casos, pode ser suficiente. No entanto, a capacidade de compartilhar objetos entre métodos Java e nativos expande o possível risco de casos muito mais traiçoeiros nos quais a manipulação imprópria de dados pode fazer com que vulnerabilidades inesperadas ou operações não seguras no código nativo corrompam estruturas de dados em Java.Redirect
. A classe declara um método JavaScript nativo, que usa JavaScript para alterar o local do documento.
import com.google.gwt.user.client.ui.UIObject;
class MyDiv {
...
public static void changeName(final UIObject object, final String name) {
changeName(object.getElement(), url);
}
public static native void changeName(final Element e, final String name) /*-{
$wnd.jQuery(e).html(name);
}-*/;
...
}
private
a partir de um método de acesso public
. private
de um método de acesso public
permite que o código de chamada modifique o conteúdo do array, fornecendo a ele acesso public
e contrariando as intenções do programador que o tornou private
.private
de um método de acesso public
.
public final class urlTool extends Applet {
private URL[] urls;
public URL[] getURLs() {
return urls;
}
...
}
public class CustomerServiceApplet extends JApplet
{
public void paint(Graphics g)
{
...
conn = DriverManager.getConnection ("jdbc:mysql://db.example.com/customerDB", "csr", "p4ssw0rd");
...
package
à classe externa original. Mais insidiosamente, como uma classe interna pode acessar os campos private
na respectiva classe delimitadora, assim que uma classe interna se tornar uma classe de mesmo nível no código de bytes, o compilador converterá os campos private
acessados pela classe interna em campos protected
.
public final class urlTool extends Applet {
private final class urlHelper {
...
}
...
}
finalize()
como public
.super.finalize()
dentro de uma implementação de finalize()
. Em situações de código móvel, a outra prática propensa a erros de coleta de lixo manual pode se tornar uma ameaça à segurança quando um invasor é capaz de invocar maliciosamente um dos seus métodos finalize()
porque ele é declarado com acesso public
. Se você estiver usando finalize()
conforme ele foi concebido, não haverá motivo para declarar finalize()
com algo diferente de um acesso protected
.public finalize()
.
public final class urlTool extends Applet {
public void finalize() {
...
}
...
}
public
, final
e static
.public
, final
e static
é um bug. Como os arrays são objetos mutáveis, a restrição de final
requer que o próprio objeto de array seja atribuído apenas uma vez, mas não faz nenhuma garantia sobre os valores dos elementos de array. Como o array é público, um programa mal-intencionado pode alterar os valores armazenados nele. Na maioria das situações, o array deve se tornar private
.public
, final
e static
.
public final class urlTool extends Applet {
public final static URL[] urls;
...
}
public
, mas não final
. public
em um Applet e em classes usadas por um Applet devem ser declaradas como final
para impedir que um invasor manipule ou obtenha acesso não autorizado ao estado interno do Applet.public
, mas não como final
.
public final class urlTool extends Applet {
public URL url;
...
}