Arbeit mit Textbausteinen in SW 6 mangelhaft

Wer von SW 5 kommt und derren Funktionen gewöhnt ist, fliegt mit SW6 teilweise auf die Nase.

  1. Warum sind die Felder bei den Textbausteinen nur einzeilig? Bei SW5 war das nicht so. Gerade bei langen Texten ist das eine undankbare Fummellei!

  2. Warum wird bei den Textbausteinen JS-Links einfach entfernt? Auch dies war in SW5 nicht so! Einen Link zur Shopauskunft einzubinden ist so nicht möglich. Gibt es hierzu einen Trick? Hängt das mit dem Editor zusammen?

Shopware 6.5? Davor sollte HTML (Javascript weiss ich nicht genau, noch nie verwendet) in den Textbausteinen erhalten bleiben.

Einzeilige Fummelei gebe ich dir Recht. Wobei das über ein Plugin relativ einfach anzupassen wäre.

Nein SW 6.4.20.2 weil ein Update auf 6.5 wegen diversen Plugins noch nicht geht.

1 „Gefällt mir“

Wenn an entsprechender Stelle im Template kein |raw steht, dann ist das Standard-twig verhalten und hat mit Shopware nichts zu tun:

Wenn beim verwendeten Textbaustein im Frontend kein raw-Filter verwendet wird, sollte HTML und JS escaped ausgegeben werden.

So wie @r4m beschreibt, wird der JS-Teil entfernt.

Falsch, denn der Teil mit dem JS wird schon beim Speichern entfernt.

Es wird definitiv beim Speichern gelöscht, wie du sagst. Habe es gerade getestet.

Im Core ist bei Feld im Snippet das AllowHTML-Flag gesetzt. Damit dürfte der HTML-Sanitizer greifen. Theoretisch sollte es reichen, wenn eine eigene „config/packages/shopware.yaml“ angelegt wird und dort das script-Tag im Basic-Set ergänzt wird:

shopware:
    html_sanitizer:
        sets:
            - name: basic
              tags: ["script", "a", "abbr", "acronym", "address", "b", "bdo", "big", "blockquote", "br", "caption", "center", "cite", "code", "col", "colgroup", "dd", "del", "dfn", "dir", "div", "dl", "dt", "em", "font", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "ins", "kbd", "li", "menu", "ol", "p", "pre", "q", "s", "samp", "small", "span", "strike", "strong", "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "tt", "u", "ul", "var"]
              attributes: ["align", "bgcolor", "border", "cellpadding", "cellspacing", "cite", "class", "clear", "color", "colspan", "dir", "face", "frame", "height", "href", "id", "lang", "name", "noshade", "nowrap", "rel", "rev", "rowspan", "scope", "size", "span", "start", "style", "summary", "title", "type", "valign", "value", "width"]
              options:
                  - key: HTML.Trusted
                    value: true

Funktioniert bei mir aber auch nicht. Selbst test- und hardcodemäßig dem Eintrag in der entsprechenden yaml-Datei im vendor-Ordner hinzugefügt, hat nichts geändert.

Der JS-Code wird bereits clientseitig entfernt und gar nicht mehr an die API zum Speichern übergeben. Vermutlich sollte da die gleiche Config greifen, das weiß ich aber nicht genau.

Prinzipiell ist es ja sinnvoll, JS standardmäßig aus Sicherheitsgründen zu entfernen. Aber es sollte auch die Möglichkeit geben, das individuell freizugeben. Ich habe aktuell keinen Weg gefunden, vielleicht fehlt irgendwo noch ein Eintrag.

Ich brauche das aktuell zwar nicht. Aber vielleicht kann jemand (von Shopware) @r4m hier einen Tipp geben.

@area-net-gmbh Danke für dein Feedback!

Ja, wobei es ist ja nicht so, dass fremde Leute irgendwo etwas eintragen. Es können nur Benutzer sein, welche auch Zugriff aufs Backend haben. Von daher kann ich diesen (möglichen) Sicherheitsaspekt nicht überhaupt nicht nachvollziehen.

Ja ich dachte auch erst an Sanitizer, aber scheint hier wohl nicht der Fall zu sein. Das bedeutet, dass auch die Eingabefelder der Textbausteine begrenzte Möglichkeiten haben.

Für mich ist das jetzt etwas Kacke, denn der Kunde will seine Grafik von Shopauskunft (geht nur per JS!) an einer bestimmte Stelle haben. Kann ich so also nicht einbinden, außer den JS-Code manuell ins Template zu hacken, was ich aber zwingend vermeiden wollte. Eine sauber Lösung ist das nicht.

eigentlich gleiches Problem wie hier?

Doch, da greift der Sanitizer. In der Entity-Definition der Snippets steht folgendes:

(new LongTextField('value', 'value'))->addFlags(new ApiAware(), new Required(), new SearchRanking(SearchRanking::HIGH_SEARCH_RANKING), new AllowHtml(), new AllowEmptyString())

Durch das „new AllowHTML()“ wird HTML erlaubt, aber durch den Sanitizer gejagt, um „schädlichen“ Code wie JS zu bereinigen. Müsste dann intern über die Klasse „StringFieldSerializer“, bzw. „AbstractFieldSerializer::sanitize()“ gehen, dort steht dann:

if ($flag instanceof AllowHtml && $flag->isSanitized()) {
            $fieldKey = sprintf('%s.%s', (string) $existence->getEntityName(), $field->getPropertyName());

            return $sanitizer->sanitize((string) $data->getValue(), [], false, $fieldKey);
        }

Im „Shopware\Core\Framework\Util\HtmlSanitizer“ sollte dann in diesem Fall das Basic-Set geladen werden. Theoretisch sollte dann eigentlich obige Anpassung funktionieren.

Aber der Code wird bereits wie gesagt clientseitig bereinigt, eventuell zieht er hier die falsche Konfig - bzw. übernimmt die eigenen Anpassungen nicht. Habe ich aber noch nicht rausgefunden. Schau da noch einmal tiefer rein.

eigentlich gleiches Problem wie hier?

Jein, im Thread geht es um 6.5 - in der das Problem noch verschärft wurde und die Bereinigung exzessive unter anderem auf CMS-Elemente ausgedehnt wurde.

Ich habe den Fehler gefunden. Wie vermutet, der clientseitige Sanitizer verwendet die Config nicht. Betreffende Datei ist „vendor/shopware/administration/Resources/app/administration/src/core/helper/sanitizer.helper.js“

Die Methode „setConfig“ wird gar nie aufgerufen. Damit wird in der Methode „sanitize“ der Standard von der eingesetzten Bibliothek DOMPurify verwendet. Und in diesem Standard fliegen script-Tags raus.

Schneller Workaround wäre die Config manuell zu setzen (ca. Zeile 90) und „bin/build-administration.js“ auszuführen:

static sanitize(dirtyHtml, config = {}) {
        var config = { ALLOWED_TAGS: ['p', 'a', 'script'], KEEP_CONTENT: true };
        return domPurify.sanitize(dirtyHtml, config);
    }

ALLOWED_TAGS dann entsprechend erweitern. Das funktioniert dann, JS wird beibehalten und im Frontend auch ausgeführt.

  • Besserer Lösungsweg: Plugin anlegen und den Teil anpassen/überschreiben
  • Noch besserer Lösungsweg: Plugin anlegen und die YAML-Config laden und verwenden
  • Königsweg: Fix durch Shopware - wenn ich dazu komme lege ich mal ein Issue an

@R4M Über den Weg wäre es aber zumindest temporär und schnell lösbar für dich und deinen Kunden.

2 „Gefällt mir“

Erst einmal vielen Dank für deine Hilfe! Ich schaue mir das mal näher an (bisher noch nicht dazu gekommen).

1 „Gefällt mir“

Leider muss ich sagen, das JS-Code zumindest bei 6.4.20.2 dennoch aus den Textbausteinen entfernt wird. Wir versuchen das jetzt ggf. über ein zusätzliches Plugin zu lösen. Für den Kunden bedeutet hat wieder zusätzliche Kosten :frowning: