Jcrop richtig anwenden

#1
Servus, ich habe da ein Problem mit Jcrop:
Also ich habe das ganze jetzt so gemacht, dass man ein Bild hochladen kann und das dann im Bildschirm angezeigt wird und man kann es mit Jcrop markieren:
Code:
<?php
  if (isset($_POST['uploadimage'], $_POST['description'])) {
    // Get image name
    $image = $_FILES['image']['name'];
    // Get text
    $description = htmlspecialchars($_POST['description']);

    // image file directory
    $target = "PIC/".basename($image);

    $image_insert = 'PIC/'.$image;
    $image_upload_statement = $pdo->prepare("INSERT INTO image_test (image, description) VALUES ('$image_insert', '$description')");
    $image_upload_statement->execute();

    if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) {
      $msg = "Image uploaded successfully";
    }else{
      $msg = "Failed to upload image";
    }
    $image_statement = $pdo->prepare("SELECT * FROM image_test WHERE image = '$image_insert'");
    $image_statement->execute();
    $image = $image_statement->fetch();

    ?>
    <main>
      <img src="<?php echo($image['image']); ?>" alt="<?php echo($image['description']); ?>" id="target" />
    </main>
    <?php

  }
?>
<main>
  <fieldset>
    <legend><h3>Bild hochladen</h3></legend>
    <form method="post" action="/?p=test_jcrop" enctype="multipart/form-data">
      <input type="hidden" name="size" value="1000000" style="padding: 6px;">
      <div>
        <input type="file" name="image" class="choose-image">
      </div>
        <input type="text" name="description" placeholder="Beschreibung" class="datafield margintop" required>
      <div>
        <input type="submit" name="uploadimage" value="Okay" class="submitbutton">
      </div>
    </form>
  </fieldset>
</main>

<script language="Javascript">
    jQuery(function($) {
        $('#target').Jcrop();
    });
</script>
Jetzt hätte ich allerdings gerne, dass die Auswahl vom Bild vorgegeben ist. Man soll sie zwar in der Größe verstellen können, das Seitenverhältnis muss aber immer gleich bleiben. Mit Klick auf einen Button, der statt dem fieldset erscheinen soll, soll der Datenbankeintrag überschrieben werden. Leider weiß ich nicht wie man das umsetzt, würde mich also über Hilfe freuen.
 

asc

Well-Known Member
c-b Experte
#3
Achtung, dein Upload-Script ist anfällig für Code-Execution Angriffe.
Niemand würde mich daran hindern da einfach eine PHP-Datei hochzuladen und dann über den direkten Pfad im Browser zu öffnen.

Lösung: finfo nutzen und validieren, dass es ein Bild ist!
 
Gefällt mir: Mat
#4
Achtung, dein Upload-Script ist anfällig für Code-Execution Angriffe.
Niemand würde mich daran hindern da einfach eine PHP-Datei hochzuladen und dann über den direkten Pfad im Browser zu öffnen.

Lösung: finfo nutzen und validieren, dass es ein Bild ist!
Naja das stört mich nur begrenzt, da nur jemand Dateien hochladen kann der Administrator ist, dafür müsste er also vorher schon mal in die DB kommen. Ich werde es mir trotzdem mal anschauen, vielen Dank für den Hinweis.
 
#5
Bezüglich des Seitenverhältnisses bei der Auswahl:

Du kannst JCrop Optionen übergeben. Bei der Anleitung gibts ein Beispiel für Aspect Ratio (falls du diese Version von JCrop hast) :
http://deepliquid.com/content/Jcrop_Manual.html#Setting_Options

Also z. B. 1 für quadratisch.
Das habe ich jetzt gemacht, funktioniert auch. Ich kriege jetzt auch Koordinaten aber dazu habe ich die Frage, ob die absolut sind oder relativ zur Größe des Bildes (also sprich ob es egal ist wenn ich es 150px breit mache oder 1500px).

Ich habe jetzt diesen Code genommen um den Bildausschnitt anzeigen zu lassen - Geht nicht. Kann es sein, dass man die style-section nicht dahin machen darf, wo ich es hingeschrieben habe oder mache ich grundsätzlich was falsch?
Code:
if(isset($_POST['uploadimagepart'])){
    $x1 = $_POST['x'];
    $y1 = $_POST['y'];
    $x2 = $_POST['x2'];
    $y2 = $_POST['y2'];
    $w = $_POST['w'];
    $h = $_POST['h'];

    $id = $_GET['id'];

    $image_statement = $pdo->prepare("SELECT * FROM image_test WHERE id = '$id'");
    $image_statement->execute();
    $image = $image_statement->fetch();

    echo $x1 . " " . $y1 . " " . $x2 . " " . $y2 . " " . $w . " " . $h;
    ?>
      <img src="<?php echo($image['image']); ?>" alt="<?php echo($image['description']); ?>" class="imagetest"/>

      <style>
        .imagetest {
          width: 200px;
          height: 150px;
          background-color: #BEBEBE;
        }

        .imagetest img {
          position: absolute;
          clip: rect(<?php echo $x1; ?>, <?php echo $y1; ?>, <?php echo $w; ?>, <?php echo $h; ?>);
          overflow: hidden;
          width: 100%;
        }
      </style>
    <?php
  }
Zur Vollständigkeit nochmal der ganze Code:
Code:
<?php
  if (isset($_POST['uploadimage'], $_POST['description'])) {
    // Get image name
    $image = $_FILES['image']['name'];
    // Get text
    $description = htmlspecialchars($_POST['description']);

    // image file directory
    $target = "PIC/".basename($image);

    $image_insert = 'PIC/'.$image;
    $image_upload_statement = $pdo->prepare("INSERT INTO image_test (image, description) VALUES ('$image_insert', '$description')");
    $image_upload_statement->execute();

    if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) {
      $msg = "Image uploaded successfully";
    }else{
      $msg = "Failed to upload image";
    }
    $image_statement = $pdo->prepare("SELECT * FROM image_test WHERE image = '$image_insert'");
    $image_statement->execute();
    $image = $image_statement->fetch();
    $id = $image['id'];

  ?>
    <main>
      <img src="<?php echo($image['image']); ?>" alt="<?php echo($image['description']); ?>" id="target" />

      <fieldset>
        <legend>Ausgewählten Bereich hochladen</legend>
        <form action="?p=test_jcrop&amp;id=<?php echo $id;?>" method="post" onsubmit="return checkCoords();">
          <input type="hidden" id="x" name="x" />
                <input type="hidden" id="y" name="y" />
          <input type="hidden" id="x2" name="x2" />
                <input type="hidden" id="y2" name="y2" />
                <input type="hidden" id="w" name="w" />
                <input type="hidden" id="h" name="h" />

          <div>
            <input type="submit" name="uploadimagepart" value="Okay" class="submitbutton">
          </div>
        </form>
      </fieldset>
    </main>
    <?php
  } ?>

  <?php
    if(isset($_POST['uploadimagepart'])){
      $x1 = $_POST['x'];
      $y1 = $_POST['y'];
      $x2 = $_POST['x2'];
      $y2 = $_POST['y2'];
      $w = $_POST['w'];
      $h = $_POST['h'];

      $id = $_GET['id'];

      $image_statement = $pdo->prepare("SELECT * FROM image_test WHERE id = '$id'");
      $image_statement->execute();
      $image = $image_statement->fetch();

      echo $x1 . " " . $y1 . " " . $x2 . " " . $y2 . " " . $w . " " . $h;
      ?>
        <img src="<?php echo($image['image']); ?>" alt="<?php echo($image['description']); ?>" class="imagetest"/>

        <style>
          .imagetest {
            width: 200px;
              height: 150px;
              background-color: #BEBEBE;
          }

          .imagetest img {
            position: absolute;
            clip: rect(<?php echo $x1; ?>, <?php echo $y1; ?>, <?php echo $w; ?>, <?php echo $h; ?>);
            overflow: hidden;
            width: 100%;
          }
        </style>
      <?php
    }
  ?>
<main>
  <fieldset>
    <legend><h3>Bild hochladen</h3></legend>
    <form method="post" action="/?p=test_jcrop" enctype="multipart/form-data">
      <input type="hidden" name="size" value="1000000" style="padding: 6px;">
      <div>
        <input type="file" name="image" class="choose-image">
      </div>
        <input type="text" name="description" placeholder="Beschreibung" class="datafield margintop" required>
      <div>
        <input type="submit" name="uploadimage" value="Okay" class="submitbutton">
      </div>
    </form>
  </fieldset>
</main>

<script language="Javascript">

  function showCoords(c) {
    $('#x').val(c.x);
      $('#y').val(c.y);
      $('#x2').val(c.x2);
      $('#y2').val(c.y2);
      $('#w').val(c.w);
      $('#h').val(c.h);
  }

  jQuery(function($) {
    $('#target').Jcrop({
      onChange: showCoords,
        onSelect: showCoords,
      aspectRatio: 16 / 9
    });
  });
</script>

<style>

  main img{
    width: 60%;
    margin: auto;
  }

  .choose-image{
   font-size: 12pt;
  }

  .submitbutton {
    text-align: center;
    border: 3px solid rgba(198,226,255,1);
    border-radius: 25px;
    background-color: rgba(0,0,255,1);
    color: rgba(198,226,255,1);
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 15px;
    padding-right: 15px;
    margin-top: 20px;
  }

  .btn-hinzu{
    width: 210px;
  }

  .btn-hinzu p{
    border: 3px solid rgba(198,226,255,1);
    border-radius: 25px;
    background-color: rgba(0,0,255,1);
    color: rgba(198,226,255,1);
    padding: 10px;
  }

  .datafield{
    width: 90%;
    font-size: 12pt;
    padding: 5px;
  }

  .margintop {
    margin-top: 15px;
  }

</style>
 

asc

Well-Known Member
c-b Experte
#6
Naja das stört mich nur begrenzt, da nur jemand Dateien hochladen kann der Administrator ist, dafür müsste er also vorher schon mal in die DB kommen.
Oder an die Session eines Administrators oder ein Administrator klickt auf einen präparierten Link oder kommt an den Rechner eines Administrators oder oder oder

Es ist ja zudem auch noch permanentes XSS möglich, d.h. es reicht wenn es einmal passiert, danach kann deine Seite permanent Schadcode ausliefern.
Wenn die Bilder mit ihrer Beschreibung zudem noch im Frontend ausgegeben werden betrifft es auch noch normale Besucher ;)

Naja, du wirst schon wissen was du da machst und welche Risiken du eingehst.
 

basti1012

Well-Known Member
#7
Ein Horror senario wäre
Man könnte mit der hochgeladene PhpDatei einmal ein glob($rdir) or array(); mit unlink() ausführen , und wenn man es richtig macht kann man die ganze Homepage löschen.
Also egal wäre mir das nicht.
 
Oben