Blog posts

StegoCore – podsumowanie po 2 tygodniach

StegoCore – podsumowanie po 2 tygodniach

Daj Się Poznać 2017, dotnetcore, security

W ostatnich dwóch postach opisałem konfigurację środowiska pracy oraz generowanie projektu przy pomocy Yeomana. Po tym wszystkim nareszcie można usiąść do pisania kodu. W związku z tym, że nie czuje się mocny we frontendzie, a i mój projekt będzie się bardziej opierał na operacjach na plikach, postanowiłem zacząć właśnie od frontendu 🙂 żeby mieć to już z głowy i zdecydować się na jakiś układ, kolorystykę itp.

Zanim zacznę od opisania tego, co udało się zrobić, wyjaśnię na początku jaki mam pomysł na aplikację i co dokładnie ma ona robić:

  • użytkownik będzie mógł przesłać plik graficzny na serwer, a następnie przeprowadzić na nim operacje steganograficzne
  • będzie możliwość ukrycie dowolnego pliku binarnego (o ile zmieści się w pliku graficznym)
  • do dyspozycji będą algorytmy
    • LSB – ukrywanie danych w najmniej znaczących bitach pliku graficznego
    • DCT – ukrywanie danych w blokach danych 8×8 z użyciem dyskretnej transformaty kosinusowej, która jest częścią algorytmu kompresji JPEG (czyli przesłany plik musi być w tym formacie)
    • Wet Paper Codes Algorithm – połączenie DCT z Wet Paper Codes właśnie (więcej o tym algorytmie w kolejnych postach)
  • plik z ukrytą informacją będzie można pobrać lub przekazać linkiem znajomemu

Dropzone.js

Za obsługę przesyłania pliku graficznego na serwer po stronie przeglądarki będzie odpowiadać dropzone.js. Jest to prosta w obsłudze biblioteka umożliwiająca opuszczanie pliku w wyznaczonym miejscu strony, a następnie wykonanie uploadu na serwer. Biblioteka została dodana do projektu jako kolejna zależność w pliku bower.json. Poniżej umieszczam moją konfigurację dropzone wraz z wyjaśnieniem. Być może komuś się przyda.

Dropzone.options.uploaddropzone = {
  paramName: "file", // nazwa elementu <input name="file" type="file" /> z formularza
  maxFilesize: 1, // maksymalny rozmiar pliku w MB
  maxFiles : 1, // maksymalna liczba plików
  previewTemplate: document.getElementById('preview-template').innerHTML, // szablon html 
  dictDefaultMessage: "Drop your file image here (1mb max)", // informacja zachęcająca do dropowania plików
  acceptedFiles: "image/*", // akceptowane typy plików
  accept: function(file, done) {
    done();
  },
  init: function() {
    this.on("addedfile", function() {
      if (this.files[1]!=null){
        this.removeFile(this.files[0]);
      }
    });
  },
  success: function(file, response) { // akcja wykonywana po wysłaniu pliku
    document.location = "/Home/ShowImage";
  },
  error: function (file, response) { // akcja wykonywana w przypadku wystąpienia błędu
    var html = '<div class="alert alert-danger alert-dismissible" role="alert">'
   + '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'
   + '<strong>Error! </strong>'+ response +'</div>';
   $("#uploaddropzone").after(html);
   this.removeFile(file);
  }
  };

Powyższa konfiguracja podpinana jest pod formularz z odpowiadającym atrybutem id (w moim przypadku uploaddropzone).

<form method="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Upload" asp-antiforgery="true" class="dropzone" id="uploaddropzone">
  <div class="fallback">
    <input name="file" type="file" />
  </div>

</form>
<div id="preview-template" style="display: none;">
  <div class="dz-preview dz-file-preview" style="margin: 0; width: 100%;">
  <div class="dz-details">
    <div class="dz-filename"><span data-dz-name></span></div>
  </div>
  <div class="progress">
    <div class="progress-bar" role="progressbar" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" style="width:0;" data-dz-uploadprogress> 
    </div>
  </div>
</div>
</div>

Dropzone podczas uploadu pliku zmienia szerokość (w zakresie 0-100%) elementu z atrybutem data-dz-uploadprogress. Dzięki temu możemy wykorzystać w tym miejscu zwykły bootsrapowy progressbar.

Upload pliku w ASP.NET Core

Dropzone po wyborze lub opuszczeniu pliku wykonuje upload pod wskazany adres. Za sam odbiór i to co zrobimy z plikiem musimy zadbać sami. Do plików wysyłanych na serwer mamy dostęp poprzez Model Binding używając interfejsu IFormFile.

[ValidateAntiForgeryToken]
[HttpPost]
public async Task<IActionResult> Upload(IFormFile file)
{
   var uploads = Path.Combine(_environment.WebRootPath, "uploads");
   if (file.Length > 0)
   {
      using (var fileStream = new FileStream(Path.Combine(uploads, file.FileName), FileMode.Create))
      {
         await file.CopyToAsync(fileStream);
      }
   }
   return Json("ok");
}

W powyższym przykładzie plik zapisywany do folderu uploads.

Na uwagę zasługuje, znany już programistom .NET z wcześniejszych wersji frameworka, atrybut [ValidateAntiForgeryToken]. Zapewnia on ochronę przez atakami typu CSRF. Działanie tego mechanizmu ochrony można opisać w trzech krokach:

  1. W formularzu, poprzez atrybut asp-antiforgery-„true”, umieszczany jest ukryty element __RequestVerificationToken, wraz z losowo wygenerowanym tokenem

    Request Verification Token
  2. Token ten zapisywany jest również w ciasteczkach
  3. Podczas requestu do akcji w kontrolerze, o ile umieścimy atrybut [ValidateAntiForgeryToken], porównywana jest wartość z formularza i ciasteczka. Jeśli są równe to request zostaje przepuszczony

 

Udało się więc zrealizować pierwszy podpunkt z planu na projekt. Hura! 😀

Co dalej?

Na razie plik graficzny zapisywany jest w folderze uploads, być może to zmienię, gdy znajdę jakiś bezpieczniejszy sposób na ich przetrzymywanie. Może ktoś z Was ma jakiś lepszy pomysł? Nie widzę jednak w aktualnym rozwiązaniu sposobu na dostanie się do plików innego użytkownika. Muszę jedynie pomyśleć o usuwaniu pliku np. po dobie od jego utworzenia.  W każdym razie, nie jest to teraz priorytetem, gdyż w końcu będę mógł zająć się biblioteką StegoCoreLib, czyli samą esencją projektu 🙂 Następy post z podsumowaniem prac nad projektem, będzie zawierał opis implementacji pierwszego algorytmu. Mam przynajmniej taką nadzieję 🙂

Wszystko co do  tej pory zrobiłem, znajduje się oczywiście na githubie. A sama strona prezentuje się tak:

StegoCoreWeb

Tak wiem, dupy nie urywa, mocne 2/10 😀  ale działa i spełnia swoje wymagania.

About the author

Senior specialist, developer. Pasjonat programowania rozwijający się przy projektach komercyjnych oraz jako kontrybutor open source. W wolnym czasie lubi pobiegać za piłką, a także obejrzeć dobry film lub serial.

1 Comment

Leave a Comment

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *