fb
WSO2 Enterprise Integrator 4 min

WSO2EI: HTTP-headers in een HTTP-respons voorkomen

Philip Akyempon
Philip Akyempon
Integration Specialist
WSO2EI Preventing HTTP headers in HTTP responses
Scroll

Richtlijnen voor de administratie van WSO2-producten omvatten beveiligingsaanbevelingen1 voor productieomgevingen. Eén van de adviezen is om de default ‘server-waarden’ van het product te updaten om te voorkomen dat er informatie over de WSO2 product stack gelekt wordt door een HTTP-header respons. Naar mijn mening zou deze aanbeveling eigenlijk moeten gelden voor de HTTP-headers van alle backend services. In deze blog demonstreer ik hoe je deze kwetsbaarheid van HTTP-headers van backend services in de WSO2 EI proxy-respons kunt verhelpen. Ik ga ook laten zien hoe de oplossing er een stokje voor kan steken door een SOAPv1.2 proxyservice te vereisen.

Banner-WSO2-Community-1-13

De proxy

De proxy service, die hieronder als voorbeeld staat, gebruikt een Respond mediator om de output van een Call mediator terug te geven aan de client die daarom vraagt. Zoals aangegeven verwacht de client een SOAPv1.2 envelope in de respons. Hieronder staan de proxy-configuraties:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="secureResponseProxy" startOnLoad="true" statistics="disable" trace="disable" transports="https">
   <target faultSequence="fault">
      <inSequence>
         <log level="full"/>
         <property expression="//*[local-name()='OrgNumber']"
name="OrganizationNumber" scope="default" type="STRING"/>
         <payloadFactory media-type="xml">
            <format>
               <web:GetOrganization
xmlns:web="http://example.organization.com">
                  <orgNumber>$ctx:OrganizationNumber</orgNumber>
               </web:GetOrganization>
            </format>
            <args/>
         </payloadFactory>
         <header name="Action" scope="default" value="http://example.organization.com/GetOrganization"/>
         <call>
            <endpoint key="organizationEndpoint"/>
         </call>
         <xslt key="transform_organiztaion_out.xslt"/>
         <property name="MESSAGE_FORMAT" value="soap12"/>
         <property action="remove" name="EXCESS_TRANSPORT_HEADERS" scope="axis2"/>
         <property action="remove" name="TRANSPORT_HEADERS"
scope="axis2"/>
         <respond/>        
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <parameter name="disableSOAP11">true</parameter>
   <description/>
</proxy>

Het is duidelijk dat deze eenvoudige proxy een organisatienummer ophaalt uit de inkomende aanvraag. Daarna wordt die informatie via een Payload transformation doorgegeven aan de backend service. De respons van de backend call wordt vervolgens geïnjecteerd in het bemiddelingsproces en daarna getransformeerd door een XSLT-mediator, waarna een Respond mediator het tot slot terugstuurt naar de client.

De richtlijn: voorkom blootstelling van backend HTTP-headers

Door gebruik te maken van de algemene eigenschappen2 TRANSPORT_HEADERS en EXCESS_TRANSPORT_HEADERS worden de HTTP-headers verwijderd als ze in de respons van de backend teruggegeven worden. Dit gebeurt voordat het bericht terug gaat naar de client. Deze beveiliging is duidelijk te zien in de onderstaande regel van de proxy service. 

<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>

Er zijn ook scenario’s waarin de backend services extra informatie in de HTTP-respons teruggeeft (zoals cookiegegevens). Deze overtollige gegevens worden bij het uitvoeren van de bewerking genegeerd door de TRANSPORT_HEADERS eigenschap. In dit soort gevallen zou ook de EXCESS_TRANSPORT_HEADERS eigenschap opgenomen moeten worden om blootstelling van dergelijke informatie te voorkomen.

<property action="remove" name="EXCESS_TRANSPORT_HEADERS" scope="axis2"/>

De valkuil: reageren met SOAPv1.2

Zoals ik eerder noemde: de client verwacht een SOAPv1.2 in de respons van de proxy. De servicedefinitie zorgt ervoor dat er aan deze eis voldaan wordt door de SOAPv1.1 uit te schakelen met de parameter disableSOAP11. Maar het verwijderen van de transportheaders gaat gepaard met het bijkomstige effect dat het bericht tijdens de bemiddeling weer teruggezet wordt naar zijn oude standaard.

Het lijkt erop dat je in zo’n geval de MESSAGE_FORMAT eigenschap met de waarde ‘soap12; aan de berichtbemiddeling kunt toevoegen en dat het bemiddelingsprobleem oplost. Deze ‘mogelijke’ oplossing zorgt er daarnaast ook nog eens voor dat er verzekert wordt de respons vanuit de proxy altijd een SOAPv1.2 envelope heeft.

<property name="MESSAGE_FORMAT" value="soap12"/>

De valkuil in deze aanpak is dat het alleen werkt als de TRANSPORT_HEADERS & EXCESS_TRANSPORT_HEADERS eigenschappen niet langer deel zijn van de sequence. En dat ondermijnt precies het idee van de beveiligingsrichtlijn.

Een alternatieve aanpak?

Ja, ik hoor het je denken: “hoe zit het met een alternatieve aanpak met een Loopback mediator in plaats van de Respond mediator. Daarna een default eindpunt in de outSequence met een format attribute van SOAPv1.2 en voila! Of misschien kun je de messageType en ContentType eigenschappen gebruiken om de berichtcontext in de bemiddeling te wijzigen.

<send>
    <default format="soap12" statistics="enable" trace="enable">
        <timeout>
            <duration>60000</duration>
            <responseAction>fault</responseAction>
        </timeout>       
     </default>
   </send>

Conclusie

Hoe verdienstelijk de gedachtegang is, de oplossing ligt in dit scenario in de Content-type Header die net voor hij naar de Respond mediator in de proxy service gaat op ‘transport scope’ gezet wordt.

<header name="Content-Type" scope="transport" value="text/xml"/> 

Deze mediator moet niet verward worden met de ContentType eigenschap die men normaal op ‘Axis2 scope’ heeft staan. Als je je hebt aangewend om de Content-Type waarde te gebruiken om het onderscheid te maken tussen SOAPv1.2 (application/soap+xml) en SOAPv1.1 (text/xml), zul je naast het verschil in de naam en de scope hierboven ook gemerkt hebben dat het onderscheid in deze context niet van toepassing is.

References:

[1] https://docs.wso2.com/display/ADMIN44x/Security+Guidelines+for+Production+Deployment

[2] https://docs.wso2.com/display/ESB500/Generic+Properties#GenericProperties-TRANSPORT_HEADERS