2012-01-11 17 views
5

Mam nieskomplikowany problem ...... który wydaje się być bardziej skomplikowany niż powinien.Niedozwolony błąd podczas wysyłania prostego formularza PHP

Mam prosty formularz służący do dodawania treści do strony internetowej. Niektóre pola muszą mieć wstawiony do nich html. Jednak po wprowadzeniu pewnych elementów html do różnych części formularza, decyduje, że nienawidzi cię i zgłasza niedozwolony błąd 403. Oto poniższy formularz:

<?php 
    $data = f("SELECT * FROM table WHERE id = '{$_GET['id']}'"); 
?> 
<form action="<?=$_SERVER['PHP_SELF']?>?id=<?=$_GET['id']?>&action=edit" method="post"> 
    <table cellspacing="0" cellpadding="2" border="0"> 
     <tr> 
      <td><b>Title:</b></td> 
      <td><input type="text" name="title" style="width: 300px;" value="<?=$data['title']?>" /></td> 
     </tr> 
     <tr> 
      <td><b>URL:</b></td> 
      <td><input type="text" name="url" style="width: 300px;" value="<?=$data['url']?>" /></td> 
     </tr> 
     <tr> 
      <td><b>Sub-Category:</b></td> 
      <td> 
       <select name="subCategoryId"> 
        <option value=""></option> 
        <option value="1">A</option> 
        <option value="2">B</option> 

       </select> 
      </td> 
     </tr> 
     <tr> 
      <td><b>Short Description:</b></td> 
      <td><textarea name="shortDescription" rows="6" cols="60"><?=$data['shortDescription']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Template:</b></td> 
      <td><textarea name="template" rows="6" cols="60"><?=$data['template']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Ads:</b></td> 
      <td><textarea name="ads" rows="6" cols="60"><?=$data['ads']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Keywords:</b></td> 
      <td><textarea name="keywords" rows="6" cols="60"><?=$data['keywords']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Questions:</b></td> 
      <td><textarea name="questions" rows="6" cols="60"><?=$data['questions']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Salary:</b></td> 
      <td><textarea name="salary" rows="6" cols="60"><?=$data['salary']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Jobs:</b></td> 
      <td><textarea name="jobs" rows="6" cols="60"><?=$data['jobs']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Meta Description:</b></td> 
      <td><input type="text" name="metaDescription" style="width: 300px;" value="<?=$data['metaDescription']?>" /></td> 
     </tr> 
     <tr> 
      <td><b>Meta Keywords:</b></td> 
      <td><input type="text" name="metaKeywords" style="width: 300px;" value="<?=$data['metaKeywords']?>" /></td> 
     </tr> 
     <tr> 
      <td>&nbsp;</td> 
      <td><input type="submit" name="submit" value="Edit Job" /></td> 
     </tr> 
    </table> 
</form> 

Mam inne formy, które podążają za tym samym wzorem bez żadnych problemów. Aby dodatkowo uczynić to jeszcze bardziej zagmatwanym, spowoduje to tylko ten błąd, gdy jakiekolwiek 2 elementy HTML zostaną dostarczone w obszarze tekstowym (obsługuje on dokładnie jeden element html). Obszary tekstowe to reklamy, słowa kluczowe, wynagrodzenia i zadania. Pozostałe obszary tekstowe będą dobrze, ale te 4 nie. Jeśli mogę sprawić, że będzie to nieco bardziej mylące, jeśli po prostu wprowadzę tekst w tych polach i zapiszę, to działa bez problemu.

Do obsługi danych postów używam tylko mysql_real_escape_string() do obsługi danych, nie używam strip_tags(), ponieważ potrzebuję tam html.

Czy jest to dziwny błąd apache, który można naprawić za pomocą .htaccess? Czy istnieje moduł w PHP, który jest w konflikcie z tym?

------- EDIT Oto odpowiedź --------

Ben wychowany wspaniałą odpowiedź, że jest prawdopodobnie problem i nie mogę go naprawić z powodu braku uprawnień . Stworzyłem więc zdarzenie onsubmit z pomysłu, który dał mi Gerben i napisałem następujący javascript.

function awesome() { 
     elements = document.forms[0].elements; 
     for(var i = 0; i < elements.length; i++) { 
      switch(elements[i].name) { 
       case "ads": 
       case "shortDescription": 
       case "template": 
       case "questions": 
       case "salary": 
       case "jobs": 
        str = elements[i].value; 
        elements[i].value = str.replace(/</g,"#@!"); 
        break; 
      } 
     } 
     return true;  
    } 

Następnie na końcu odbiorczym zrobiłem str_replace, aby zastąpić # @! z powrotem do < i to przynajmniej sprawiło, że wszystko działało.

Jestem na koniu .... hyaa!

Dzięki za pomoc. :)

+1

Czy można również opublikować kod, który jest odpowiedzialny za przetwarzanie zgłoszenia? Może to być problem przekierowania lub obsługi błędów generowany przez walidację php. –

+1

Czy adres URL wygląda inaczej podczas przesyłania formularza, jak ma to miejsce w adresie URL samej strony formularza? – Gerben

+0

@BenD Naprawdę nie ma żadnego kodu odpowiedzialnego za przetwarzanie zgłoszenia. Jest to proste polecenie foreach, które uruchamia vars $ _POST i rzuca na nie mysql_real_escape_string. Nie ma żadnej walidacji javascript. Po prostu naciśniesz przycisk submit, ładuje tę samą stronę, po prostu wpada w instrukcję switch, która powinna wylądować w obszarze, aby zaktualizować informacje. Działa na wszystko inne (ta sama instrukcja foreach) w innych częściach witryny, ale nie tutaj, gdy zaangażowanych jest wiele elementów html. – n0nag0n

Odpowiedz

7

Biorąc pod uwagę, że jesteś w stanie publikować posty, a obsługa jest najwyraźniej bardzo prosta i tak mało prawdopodobne jest, aby rzucić 403 błędy lub przekierować do zabronionych katalogów, zamierzam zaryzykować przypuszczenie, że " ponownie uruchamia zaporę na poziomie serwera apache. Spójrz na swoje pliki konfiguracyjne Apache i sprawdź, czy używasz mod_security lub jakiegokolwiek innego modułu zapory. Istnieje wiele sposobów, w jakie można skonfigurować mod_security, w tym skanowanie danych POST dla treści html i odpowiednio reagować. Jeśli jest skonfigurowany, aby zapobiec wstrzykiwaniu html, może to być twój problem (zobacz szczegóły konfiguracji tutaj: http://www.modsecurity.org/projects/modsecurity/apache/feature_content_injection.html).

Aby to sprawdzić, spróbuj dodać plik .htaccess w katalogu głównym internetowej (zakładając, że masz prawo do zastąpienia apache ustawienia za pomocą htaccess) i ustawienie:

SecFilterEngine Off 

Restart apache, a następnie sprawdzić, czy to wciąż dzieje.

Jeśli jest to host współdzielony lub w inny sposób nie masz możliwości modyfikowania ustawień apache, możesz spróbować obejść za pomocą javascript, że base64 encodes wszystkie dane przed przesłaniem (onsubmit), a następnie base64_decode ($ _ POST [ klucz]) w skrypcie php, który je przetwarza.

+1

Myślę, że nie mogę przesłonić tej funkcji. Zrobiłem phpinfo(); i nie widziałem nic na temat zapory ani mod_security. Próbowałem wprowadzić kod do pliku htaccess i dało mi to błąd serwera wewnętrznego 500. Jest to kolejne konto klienta i używają one fastwebhost.com, które ... blokuje twój adres IP, jeśli źle oddychasz. – n0nag0n

+0

Dzięki za pomoc. Rozgryzłem to z pomocą twojej i Gerbena. – n0nag0n

+0

To także świetny pomysł. Mój jest więcej ...... nowicjusz i ..... tak, nowicjusz. :) – n0nag0n

1

Po prostu miałem ten sam rodzaj problemu przy wysyłaniu pokazał błąd 403, ale dla mnie było to proste, ponieważ formularz był zbyt duży, wyzwalając regułę mod_security.

Warto również zwiększenie php.ini post_max_size i wielkość badanie przy użyciu: $_SERVER['CONTENT_LENGTH']

0

może być odrobinę późno, ale mam do czynienia z podobnym problemem dziś, starając się złożyć formularz za pośrednictwem POST. Nie pozwoliłoby mi na przesłanie tekstu z linkiem i spowodowałoby błąd 403 Forbidden Acess Denied. Wyłączenie modsecurity (zrobiłem to z panelu sterowania) rozwiązałem!

Powiązane problemy