Printf não é seguro para usar em C

Sep 24 2020

Eu sou novo em C, então comecei a brincar com alguns códigos. Tenho um bug no meu código porque acredito que printf(pass)não seja seguro usar o uso, porque pode substituir o valor e, portanto, não é seguro para o usuário. Eu queria saber se estou certo sobre isso printf(pass)não é seguro no meu código? Além disso, como posso permitir que o usuário imprima a mensagem finally logged insem alterar meu código. Existe alguma maneira de fazer isso?

Meu código:

#include <stdio.h>

char pass[100];

char getPass() {
  int value = 'G';
  int * j = & value;
  fgets(pass, sizeof(pass), stdin);
  printf("your entered pass is ");
  printf(pass);
  return (char)( * j);
}

void main() {
  printf("enter the pass here ");
  if (getPass() == 'K') {
    printf("finally logged in\n");
    exit(0);
  } else {
    printf("Wrong password\n");
    exit(1);
  }
}

Respostas

5 r3mainer Sep 24 2020 at 08:48

Sim, não é seguro, mas não pelo motivo que você sugeriu. Se você verificar a manpágina da printf()função, verá que ela tem o seguinte protótipo:

int printf(const char * restrict format, ...);

O constmodificador aplicado ao primeiro argumento especifica que o valor deste parâmetro não será alterado quando você chamar esta função.

No entanto, você também notará que esse parâmetro é chamado format. Isso porque ele deve especificar uma string de formato. Em seu programa, não há nada que impeça um usuário de inserir um especificador de formato como %p, nesse caso, sua chamada para printf()começará a imprimir o conteúdo da pilha. Há um artigo da Wikipedia que descreve essa vulnerabilidade com mais detalhes.

4 VladfromMoscow Sep 24 2020 at 08:45

A função, fgetsse sua chamada foi bem-sucedida, fornece uma string que você pode enviar.

Pode surgir um problema se a string obtida for emitida de forma

printf(pass);

e contém especificações de conversão.

Então, em vez dessa ligação

printf(pass);

é mais seguro de usar

printf( "%s", pass );

ou

puts(pass);

Preliminar, você pode remover o caractere de nova linha armazenado na string pela chamada de fgets.