Vai al contenuto
Avanet

Gestire la quarantena di Sophos Email tramite API

La Email Quarantine API elabora i messaggi che Sophos Email ha spostato nella normale quarantena di sicurezza email prima della consegna. La procedura sicura consiste nell’eseguire una ricerca mirata, valutare ogni pagina, registrare X-Sophos-Email-ID e destinatario, ispezionare il contenuto, apportare una modifica di portata limitata e verificare il risultato per ciascun destinatario.

Questo articolo usa esclusivamente percorsi sotto /email/v1/quarantine. La Post-Delivery Quarantine, dal nome simile, riguarda messaggi già consegnati e successivamente ritirati e dispone di una propria famiglia di endpoint. Non mischiare i relativi percorsi, ID o stati con questa procedura.

Preparare prerequisiti e variabili

Completare prima l’introduzione alla Sophos Email Management API. La guida pianificata Autenticare la Sophos Email API e instradare le richieste al tenant approfondisce Service Principal, risoluzione del tenant e autorizzazioni minime. I valori seguenti devono essere già stati determinati in modo sicuro:

  • SOPHOS_ACCESS_TOKEN: token bearer OAuth2 di breve durata;
  • SOPHOS_TENANT_ID: UUID del tenant di destinazione;
  • SOPHOS_API_HOST: host API regionale di tale tenant;
  • un’autorizzazione Email Quarantine assegnata al Service Principal.
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"

Token, URL di download, password ZIP, header MIME e testo dei messaggi sono segreti o dati personali. Non devono apparire nella cronologia della shell, negli argomenti dei processi, nell’output CI o nei ticket. I blocchi JSON seguenti sono volutamente esempi di documentazione; i client di produzione scrivono i payload in file temporanei protetti o li trasmettono tramite standard input.

I contratti descritti sono stati verificati con la Email Management API v1.4.0. Prima dell’implementazione, ricontrollare metodo, percorso, schema, autorizzazione e limiti nella specifica corrente.

Cercare in modo mirato e impaginare tutti i risultati

POST /quarantine/messages/search richiede beginDate e endDate come istanti ISO 8601. I filtri sono facoltativi. L’esempio limita un caso di malware in entrata a un destinatario e richiede 100 record, il massimo documentato per pagina di ricerca:

{
  "beginDate": "2026-09-14T00:00:00.000Z",
  "endDate": "2026-09-15T00:00:00.000Z",
  "pageSize": 100,
  "sort": ["quarantinedAt:DESC"],
  "filter": {
    "direction": "inbound",
    "toContains": "analyst@example.test",
    "reason": ["malware"]
  }
}

Il contratto del filtro comprende id, fromContains, toContains, subjectContains, attachmentNameContains, hasAnyAttachment, sizeInMBGreaterThan, sizeInMBLowerThan, direction (inbound o outbound), productType (mailflow, gateway o ems) e reason. I campi di ordinamento documentati sono from, forRecipient e quarantinedAt. Con fields è possibile richiedere una risposta parziale; il client non deve interpretare i campi omessi come valori vuoti.

La risposta contiene items e pages. Per la pagina successiva, copiare pages.nextKey senza modifiche e come stringa in pageFromKey nel corpo POST successivo. Terminare solo quando nextKey non è più presente e proteggere inoltre il ciclo con limiti al numero di pagine e alla durata e con il rilevamento di chiavi ripetute. pages.size descrive soltanto la pagina corrente. Una prima pagina piena o vuota non dimostra quindi né la completezza né l’assenza di altri risultati.

Per ogni risultato registrare almeno id, forRecipient, reason, quarantinedAt, direction e l’operazione pianificata. id è l’UUID dell’header MIME X-Sophos-Email-ID; mimeMessageId è il normale header Message-ID e non lo sostituisce in un percorso API o in un corpo bulk. Uno stesso messaggio può produrre risultati specifici per destinatario.

Ispezionare messaggio, URL e allegati

Tutte e tre le operazioni di lettura usano nel percorso il valore id codificato per URL:

GET /quarantine/messages/{id}/preview
GET /quarantine/messages/{id}/urls?pageSize=50&page=1
GET /quarantine/messages/{id}/attachments?pageSize=50&page=1

L’anteprima restituisce headers, htmlBody e textBody. Trattare l’HTML come contenuto ostile: non renderizzarlo direttamente in un browser o portale amministrativo, non caricare risorse esterne e non aprire i link inclusi. Per l’analisi preferire testo e singoli header.

Gli elenchi di URL e allegati utilizzano pagine numerate a partire da 1. Il valore predefinito di pageSize è 50; la risposta indica il massimo consentito in pages.maxSize e, secondo lo schema verificato, può contenere fino a 500 elementi. Continuare finché pages.current raggiunge l’ultima pagina indicata o finché segue una pagina vuota. Non usare qui il modello a chiavi della ricerca (nextKey).

Un record URL è un’indicazione, non un giudizio di sicurezza. Un record allegato contiene name, sizeInBytes, fileType e stripped. Le azioni identificano gli allegati tramite il nome documentato, non mediante un UUID allegato inventato. In presenza di nomi duplicati o di un elenco inatteso, non fare supposizioni: chiarire il caso manualmente.

Scaricare, rimuovere o riapplicare gli allegati

Il download è asincrono e avviene in due fasi. Avviare innanzitutto un job per un messaggio. Se attachments viene omesso, il job comprende tutti gli allegati; un elenco esplicito è più sicuro in un caso controllato:

POST /quarantine/messages/{id}/attachments/download
{
  "attachments": ["sample.zip"]
}

La risposta contiene almeno id e status del job. Questo ID diventa il downloadId del percorso di stato e non deve essere confuso con l’ID del messaggio:

GET /quarantine/downloads/{downloadId}/status

Eseguire il polling con backoff limitato finché status è completed o failed. Con completed possono apparire attachments, un url firmato e una password per lo ZIP protetto. L’URL è materiale di accesso di breve durata: scaricarlo subito esclusivamente in un ambiente di analisi isolato e approvato, non registrarlo mai e, se scade, usare lo stato del job o un nuovo job di download autorizzato. Con failed, valutare error; il client non deve avviare una serie infinita di nuovi job.

Strip e reattach modificano lo stato degli allegati per destinatario:

POST /quarantine/messages/{id}/attachments/strip
POST /quarantine/messages/{id}/attachments/reattach
{
  "attachments": ["sample.zip"],
  "forRecipients": ["analyst@example.test"]
}

forRecipients limita la modifica. Senza questa restrizione, l’azione può interessare altri destinatari del messaggio. Separare sempre la risposta in items riusciti ed errors non riusciti. Recuperare poi di nuovo l’elenco degli allegati e verificare stripped per il nome previsto. Reattach non rilascia il messaggio e non dimostra che l’allegato sia sicuro.

Rilasciare o eliminare messaggi in modo controllato

Release e delete accettano al massimo 50 record per richiesta. Ogni record richiede X-Sophos-Email-ID; forRecipients è facoltativo, ma rappresenta la restrizione sicura per un’operazione specifica per destinatario.

POST /quarantine/messages/release
POST /quarantine/messages/delete

Un rilascio strettamente limitato ha questo aspetto:

{
  "items": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "forRecipients": ["analyst@example.test"],
      "stripAttachments": ["sample.zip"]
    }
  ],
  "allowSender": false,
  "enforceSenderAuthentication": false,
  "submitMessageToLabs": false
}

Release restituisce HTTP 202: il messaggio è stato accettato e messo in coda per il rilascio, non consegnato in modo comprovato. allowSender e enforceSenderAuthentication restano false per impostazione predefinita. Consentire un mittente solo dopo un’approvazione di sicurezza separata; se si abilita deliberatamente allowSender, non lasciare inavvertitamente disattivata l’autenticazione del mittente. submitMessageToLabs si applica soltanto ai messaggi spam e virus. stripAttachments agisce per singolo record di rilascio.

Richiedere l’eliminazione separatamente e senza bloccare implicitamente il mittente:

{
  "items": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "forRecipients": ["analyst@example.test"]
    }
  ],
  "blockSender": false
}

Delete restituisce HTTP 200 in caso di successo. blockSender è una modifica delle policy aggiuntiva e più ampia e resta false senza una richiesta di blocco approvata. Non ripetere automaticamente release o delete dopo un timeout: il server potrebbe avere già accettato la prima richiesta.

Entrambe le risposte bulk possono contenere contemporaneamente items ed errors. Il successo HTTP non significa quindi che tutte le coppie ID/destinatario siano riuscite. Confrontare ciascuna coppia richiesta esattamente una volta con entrambi gli array; risultati mancanti, duplicati o contraddittori devono impedire una conferma automatica di successo.

Verificare il risultato

Eseguire questi controlli per ogni modifica:

  1. Registrare request ID o correlation ID, stato HTTP, orario, tenant e un elenco oscurato delle coppie ID/destinatario; non memorizzare contenuti o segreti.
  2. Per strip/reattach, elencare nuovamente gli allegati e controllare stripped per ogni nome.
  3. Per release, valutare tutti gli items e gli errors, ripetere la stessa ricerca in quarantena e confermare la consegna effettiva mediante la prova operativa prevista. Il solo 202 non è sufficiente.
  4. Per delete, valutare tutti gli items e gli errors e ripetere la stessa ricerca. Considerare un record assente come prova solo insieme alla risposta bulk positiva, poiché intervalli temporali e filtri possono anch’essi nascondere risultati.
  5. Per i download, confrontare downloadId, stato finale e nomi richiesti; rimuovere URL e password dalla memoria e dall’archiviazione temporanea al termine.

Risolvere errori parziali, job scaduti e autorizzazioni

  • Una parte dell’azione bulk non riesce: Valutare errors per id, recipient ed error. Non reinviare le coppie riuscite. Elaborare in una nuova richiesta soltanto le coppie in errore ancora esistenti e nuovamente approvate.
  • 400 Bad Request: Controllare tipi JSON, campi obbligatori, istanti ISO, UUID, valori enum, modello di paginazione e i rispettivi limiti di 50 o 100. pageFromKey è una stringa, non un numero di pagina.
  • 401 o 403: Rinnovare il token tramite il normale flusso OAuth2 oppure controllare l’assegnazione al Service Principal, l’autorizzazione Email Quarantine e il tenant. Non passare a un altro tenant o host.
  • 404 o ID non valido: Verificare che l’UUID provenga da X-Sophos-Email-ID, esista ancora nella quarantena normale e appartenga al tenant. Non usare mimeMessageId, downloadId o un ID della Post-Delivery Quarantine.
  • Il download resta processing: Limitare intervallo e durata totale del polling, controllare ID del job e tenant e inoltrare il caso con request/correlation ID. Non avviare continuamente nuovi job paralleli.
  • Il download è failed o l’URL è scaduto: Conservare error, ricontrollare lo stato e avviare un nuovo download solo se la richiesta resta valida. Non modificare né riutilizzare un URL firmato.
  • L’allegato manca o il suo stato è diverso: Leggere tutte le pagine numerate degli allegati, confrontare esattamente i nomi e controllare gli errors per destinatario. Fermarsi in caso di nomi duplicati o se il messaggio è già stato rilasciato.
  • Il rilascio scompare dall’elenco ma non arriva: È stato soltanto messo in coda. Controllare il destinatario, ripetere i filtri e verificare le prove di consegna successive; non rilasciarlo automaticamente di nuovo.

Un’escalation deve includere versione API, host regionale senza credenziali, ID tenant, intervallo UTC, metodo e percorso, stato HTTP, request/correlation ID e ID oggetto e codici di errore oscurati. Escludere token, URL firmati, password ZIP, testo dei messaggi e allegati.