Un'applicazione web che sto sviluppando sarà un'applicazione singola pagina (SPA) che interagirà con un backend API REST, attraverso chiamate jQuery.ajax()
.
La SPA e l'API saranno entrambe servite tramite una connessione https / TLS. L'API verrà servita da un sottodominio del dominio SPA:
SPA: example.org
API: api.example.org
... e risponderà con le intestazioni CORS appropriate:
Access-Control-Allow-Origin: example.org
Access-Control-Allow-Methods: GET, POST, etc. // whatever applicable to the requested resource
Access-Control-Allow-Headers: Accept, Authorization, Content-Type
All'accesso al centro SPA l'utente (un'organizzazione) riceverà il suo sha1 API-key
unico associato (in un cookie o come variabile javascript globale), che SPA utilizzerà per interagire con l'API, per il durata della sessione di accesso dell'utente. La SPA rilascerà questo API-key
in ogni richiesta all'API in un'intestazione Authorization
:
Authorization: MyAppsApi apikey=<API-key>
L'archiviazione di persistenza dell'API REST sarà basata su XML. Non ho ancora deciso un fornitore di meccanismo di archiviazione effettivo (considerando l'utilizzo di eXistdb , al momento). In questa fase iniziale di sviluppo, tuttavia, sto semplicemente usando PHP DOMDocument
e DOMXPath
, senza capacità di lettura / scrittura simultanee.
L'API REST genererà inoltre dinamicamente le query XPath, in base al percorso dell'URI della richiesta ricevuta. La comunicazione tra SPA e API verrà probabilmente eseguita in JSON, tuttavia.
Considera questo documento XML di esempio:
<?xml version="1.0" encoding="utf-8"?>
<organisations>
<organisation id="1">
<apiKey>some hex sha1 digest</apiKey>
<products>
<product id="1">
<parts>
<part id="1">
<subParts>
<subPart id="1">
...
</subPart>
</subParts>
</part>
</parts>
</product>
</products>
</organisation>
<organisation id="2">
<apiKey>another hex sha1 digest</apiKey>
<products>
...
</products>
</organisation>
</organisations>
Attualmente, questo documento è convalidato da uno schema XSD personalizzato.
L'API REST determinerà innanzitutto se esiste un nodo <organisation>
con il <apiKey>
emesso prima di interagire ulteriormente con l'XML. Se viene trovato il nodo <organisation>
, verrà utilizzato come nodo di contesto per ulteriori query XPath.
I percorsi URI della richiesta saranno limitati dal seguente modello regolare:
~\G(/(?<collection>[a-z]+)(?:/(?<resourceId>\d+))?)(?:(?=(?1))|/?$)~
che consente solo /<loweralpha>+(/<digit>+)?
segmenti
Considera questi percorsi URI di richiesta di esempio e il loro XPath generato dinamicamente:
/products/1 => .//products/*[@id="1"]
/parts/1 => .//parts/*[@id="1"]
/products/1/parts/1 => .//products/*[@id="1"]/parts/*[@id="1"]
Come puoi vedere, saranno relativi al nodo di contesto <organisation>
.
Considerando che non ho ancora studiato a fondo il tipico funzionamento dei backend XML, potrebbe benissimo risultare che la mia precedente configurazione XML è imperfetta per cominciare, nel senso che dovrei creare un documento XML per organizzazione, mitigando il rischio di accesso ai nodi che non appartengono al nodo di contesto <organisation>
.
Tuttavia, vedi qualche difetto intrinseco in questa configurazione attuale?
Nel mio attuale assetto sono principalmente preoccupato delle query XPath dinamiche che potrebbero rivelarsi troppo rischiose. Forse un avversario è in grado di intrufolarsi nelle asce XPath, in qualche modo? Ma mi interessa anche conoscere altri possibili difetti.
Grazie.
PS .: forse avrei dovuto chiarire di più quali sono i rischi, di cui sono più interessato:
- Può un avversario ottenere in qualche modo la chiave API di una (altra) organizzazione?
- Può un avversario in qualche modo manipolare il contenuto di una (altra) organizzazione?