Atualizado em 20 de Dezembro de 2013

Como Forçar Download com Segurança no PHP

Olá pessoal,

Uma dúvida que sempre surge quando estamos desenvolvendo um site que contenha uma área com downloads e de como evitar que o navegador mostre o arquivo ao invés de fazer o download do mesmo, já que algumas extensões de arquivos como jpg, pdf, txt e etc são abertas no próprio navegador.

O script que vamos estudar ele aborda dois assuntos importantes. O primeiro e forçar o download de um arquivo com PHP e o segundo ponto refere-se a segurança pois quando temos um script que força o download do arquivo um usuário mal intencionado pode tentar fazer download de arquivos não permitidos.

Vamos ao script:

<?php
/*
  * Dica: Sempre mantenha os arquivos de download em uma mesma pasta, separada dos arquivos do site.
  * Neste script usaremos a pasta download para esta função.
 */


$arquivo = 'imagem_teste.jpg'; // Nome do Arquivo
$local = 'download/'; // Pasta que contém os arquivos para download
$local_arquivo = $local.$arquivo; // Concatena o diretório com o nome do arquivo

/*
  * Por segurança, o script verifica se o usuário esta tentato sair da pasta especificada para
  * os arquivos de download (stripos($arquivo, './') !== false || stripos($arquivo, '../') !== false),
  * isso irá bloquear a tentativa de forçar download de arquivos não permitidos.
  * Na mesma função verificamos se o arquivo existe (!file_exists($arquivo)).
  */

if(stripos($arquivo, './') !== false || stripos($arquivo, '../') !== false || !file_exists($local_arquivo))
 {
  echo 'O comando não pode ser executado.';
 }
else
 {
  header('Cache-control: private');
  header('Content-Type: application/octet-stream');
  header('Content-Length: '.filesize($local_arquivo));
  header('Content-Disposition: filename='.$arquivo);
  header("Content-Disposition: attachment; filename=".basename($local_arquivo));

  // Envia o arquivo Download
  readfile($local_arquivo);
 }
?>

Download do script Clique aqui. Este script e de grande utilidade, aproveitem.


"Esta dica te ajudou de alguma forma?" Então ajude outras pessoas compartilhando este conteúdo com seus amigos! =)


Até a próxima.

Comentários

Sua foto do perfil

Cristiano G.G. Fonseca

Muito bem explicado de facil entendimento...Parabens e obrigado pelas dicas

05 de Janeiro de 2016 - 19:26

Sua foto do perfil

Egberto

Fiz o seu exemplo certo, mas na hora de executar o script ele simplesmente le o arquivo, no meu caso estou forçando download com arquivos torrents será que tem alguma coisa haver ?

12 de Outubro de 2015 - 20:51

Sua foto do perfil

Mauricio Programador

Olá Egberto,

Estes arquivos estão em um servidor seu?

Abraço.

19 de Outubro de 2015 - 15:51

Sua foto do perfil

Egberto Sullivan

Sim mauricio estão em meu servidor sim. Abraços

20 de Novembro de 2015 - 14:35

Sua foto do perfil

Mauricio Programador

Egberto,

então não tem problema nenhum, o único pré-requisito para este script e que ele não pode estar na mesma pagina HTML, e sim em um arquivo separado somente com o código de download.

O seu esta assim?

Abraço.

20 de Novembro de 2015 - 14:35

Sua foto do perfil

egberto sullivan

Entendi Mauricio,
Então o problema é esse meu script está dentro de uma requisição jquery que abre dentro da página que contém o html, será que posso colocar a requisição logo no inicio da página antes de iniciar o código html.

23 de Novembro de 2015 - 14:24

Sua foto do perfil

Mauricio Programador

Na verdade não, pois o que faz ele forçar o download e exatamente trazer um arquivo com a extensão original na qual o navegador não consegue exibir e assim fazer o download.

Abraço.

23 de Novembro de 2015 - 14:24

Sua foto do perfil

Jackson

Olá Maurício,

Obrigado pelo post. Mas comigo não deu certo. Ocorre o download do arquivo, mas quando vou abrir dá erro e isso ocorre com todas as extensões, como se estivesse corrompido. Sabe o que pode estar causando isso?

Abraço.

25 de Novembro de 2014 - 10:26

Sua foto do perfil

Mauricio Programador

Olá Jackson,

O que pode estar acontecendo e você estar usando esta pagina junto com outro conteúdo HTML.

Tente colocar um link para este arquivo, sem nenhum conteúdo a mais, somente este script e veja se funciona.

Qualquer coisa posta ai.

Abraço.

26 de Novembro de 2014 - 08:35

Sua foto do perfil

Juliano

OLÁ MAURICIO.
tenho um problema quanto ao download do arquivo pois ele em certo tempo interrompe, o arquivo que tento baixar tem 70mb, e não chega a baixar 30mb
vc pode me ajudar?

09 de Outubro de 2014 - 14:48

Sua foto do perfil

Mauricio Programador

Olá Juliano,

Primeiro passo seria testar o mesmo procedimento local (em seu servidor local). Isso para verificar se é o seu servidor ou o código que esta com algum erro.

Se no teste local der certo, veja a configuração do seu php.ini do servidor para verificar se não esta limitado o tamanho do download.

Se não resolver posta ai.

Abraço.

10 de Outubro de 2014 - 09:23

Sua foto do perfil

JUSCELINO DAMASCENO

Obrigado pela ajuda...
seu script foi perfeito no arquivo jpg que eu queria forçar o download.
Forte abraço.

24 de Setembro de 2014 - 13:01

Sua foto do perfil

Renato Alencar

Você não precisaria criar duas variaveis e depois concatenar, seria desperdicio de memória, e não precisa usar stripos(...) !== false, bastava stripos(...), funciona igual. E poderia dificultar mais a ação de invasores unsando header('Location: /'), além disso, só a verificação de se começa com '../' não iria adiantar se o atacante soubesse o diretória do site poderia facilmente usar o caminho completo começando com '/'. Já vi muito site que tinha muita proteção contra todo tipo de coisa, SQL Injection, etc, mas o script de download dava acesso aos arquivos que continhão as informações para acesso do banco de dados, não custa nada ter cuidado.

09 de Março de 2014 - 13:49

Sua foto do perfil

Mauricio Programador

Olá Renato,

com certeza, você esta correto. Alguns recursos usados aqui neste script e mais para usuários que não tem muito conhecimento e para tornar o post mais didático fiz desta forma.

Mas sua dica e muito legal, obrigado pela contribuição.

10 de Março de 2014 - 09:38

Sua foto do perfil

Leomar Junio

Amigo, ótimo post obrigado pela contribuição!
Gostaria de fazer uma pergunta:

Estou desenvolvendo um script para pegar os vídeo Uol e baixa-los, no caso já conheço e tenho o endereço deles em mp4, porem olhando seu script fico em duvida com se faz para pegar o o vídeo, pois o mesmo alem de não ser hospedado em meu site ele o nome dele não leva extenção no final !

Este é o link " http://video25.mais.uol.com.br/14335697.mp4?ver=0&start=0&r=http%3A%2F%2Fplayer.mais.uol.com.br %2Fplayer_video_v2.swf%3FmediaId% 3D14335697%26p%3Dmais%26tv%3D0 "

Alguma ideia ? Obrigado pela atenção!

28 de Fevereiro de 2014 - 13:55

Sua foto do perfil

Mauricio Programador

Olá Leomar, Obrigado.

na verdade este script e somente para funcionamento interno, ou seja, no seu próprio site. Para fazer o script que você deseja terá que ser de outra forma.

Quanto ao site da UOL não saberia dizer, pois nunca fiz um projeto especifico dele e não sei se eles bloqueia este tipo de ação, pois alguns site fazem o bloqueio.

Abraço.

28 de Fevereiro de 2014 - 14:21

Sua foto do perfil

Leomar Junio

Mauricio muito obrigado pela atenção e pela resposta rápida!

Eles não broqueiam não, fiz teste usando html5
baixar funcionou blz em alguns navegadores,mais em outros não, de qualquer forma muito obrigado pela atenção!

28 de Fevereiro de 2014 - 15:23

Sua foto do perfil

Mauricio Programador

Legal, então você poderia tentar fazer um file_get_contents para pegar o conteudo do outro site, não sei se iria funcionar teria que testar mesmo.

Abraço e sucesso.

28 de Fevereiro de 2014 - 15:24

Sua foto do perfil

Leomar Junio

Ok Mauricio, irei estudar esta string que você sitou, e também vou tenar me aprofundar no header , e em ultimo caso tento ver o cUrl.

Obrigado mais uma vez!

28 de Fevereiro de 2014 - 17:05

Sua foto do perfil

anderson cavalcantti

nao funciona com extenção JPG EM CAIXA ALTA

27 de Dezembro de 2013 - 22:08

Sua foto do perfil

Mauricio Programador

Olá Anderson,

não fiz o teste com ele em caixa alta, até porque o padrão de todos os arquivos web é serem minusculo.

Mas para todos os efeitos você pode renomear o arquivo para ele ficar correto.

Abraço.

28 de Dezembro de 2013 - 08:33

Sua foto do perfil

Anderson Krueger

Boa Noite Mauricio, ótimo post, mas venho aqui relatar e peço sua ajuda para saber como fazê-lo, pois em meu caso o uso de quaisquer headers relacionados a forçar o download que pude verificar que eles em minhas tentativas baixam o arquivo com o nome especificado na variável arquivo, porém seu conteúdo eh o html da pagina na qual esta inserido, sabe me explicar porque, agradeço desde já agradeço, Anderson Krueger, iniciante na área de programação em php

08 de Dezembro de 2013 - 20:41

Sua foto do perfil

Mauricio Programador

Olá Anderson,

Não sei se entendi muito bem sua pergunta. Você usou este script e quando vai ver o arquivo que baixou o conteudo dele é o html da pagina onde ta os arquivos para download.

Se for isso, é que na verdade este script não pode estar na mesma pagina onde ta o html, ele deve ta em um arquivo separado, somente para fazer esta função.

Qualquer coisa posta aí.

grande abraço.

09 de Dezembro de 2013 - 09:49

NEWSLETTER

Receba dicas de programação
em seu e-mail

TWITTER

Acompanhe tudo o que rola
com Mauricio Programador

NEWSLETTER