fix: 🐛 fix latest security "fix"

This commit is contained in:
Erik Hellman 2021-03-25 14:33:57 +01:00
parent b611228ab4
commit d7954587d5
2 changed files with 34 additions and 17 deletions

View File

@ -42,6 +42,8 @@ export class Api extends EventEmitter {
public isFake: boolean = false public isFake: boolean = false
public childControllerUrl?: string
constructor(fetch: Fetch, cookieManager: CookieManager, options?: FetcherOptions) { constructor(fetch: Fetch, cookieManager: CookieManager, options?: FetcherOptions) {
super() super()
this.fetch = wrap(fetch, options) this.fetch = wrap(fetch, options)
@ -127,6 +129,12 @@ export class Api extends EventEmitter {
const text = await response.text() const text = await response.text()
const doc = html.parse(decode(text)) const doc = html.parse(decode(text))
const xsrfToken = doc.querySelector('input[name="__RequestVerificationToken"]').getAttribute('value') || '' const xsrfToken = doc.querySelector('input[name="__RequestVerificationToken"]').getAttribute('value') || ''
const scriptTags = doc.querySelectorAll('script')
const childControllerScriptTag = scriptTags.find((elem) => {
const srcAttr = elem.getAttribute('src')
return srcAttr?.startsWith('/vardnadshavare/bundles/childcontroller')
})
this.childControllerUrl = routes.baseEtjanst + childControllerScriptTag?.getAttribute('src')
this.addHeader('x-xsrf-token', xsrfToken) this.addHeader('x-xsrf-token', xsrfToken)
} }
@ -159,16 +167,25 @@ export class Api extends EventEmitter {
return authBody return authBody
} }
private async retrieveCreateItemXsrfToken(url: string) { private async retrieveCreateItemHeaders(url: string) {
const response = await this.fetch('childcontrollerScript', url, {}) const config = {
method: 'GET',
headers: {
Pragma: 'no-cache',
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
}
}
const response = await this.fetch('childcontrollerScript', url, config)
const text = await response.text() const text = await response.text()
const xsrfRegExp = /'(x-xsrf-token[\d]+)':[ ]?'([\w\d_-]+)'/gim
const xsrfMatches = xsrfRegExp.exec(text)
return xsrfMatches && xsrfMatches.length > 2 const headerRegexp = /{\s*headers:\s*({.+})}/gis
? {'xsrfTokenName': xsrfMatches[1], 'xsrfTokenValue':xsrfMatches[2]} const matches = text.match(headerRegexp)
: {'xsrfTokenName': 'x-xsrf-token', 'xsrfTokenValue':''} if (matches && matches.length >= 1) {
console.log('Matches:', matches[0])
return JSON.parse(matches[0].replace(/ /g,'').replace(/\'/g,'"').replace(/headers:/g,'"headers":'))
} else {
return null
}
} }
private async retrieveAuthToken(url: string, authBody: string): Promise<string> { private async retrieveAuthToken(url: string, authBody: string): Promise<string> {
@ -189,14 +206,12 @@ export class Api extends EventEmitter {
this.cookieManager.clearAll() this.cookieManager.clearAll()
// Perform request // Perform request
const {xsrfTokenName, xsrfTokenValue} = await this.retrieveCreateItemXsrfToken(routes.childcontrollerScript) let scriptUrl = this.childControllerUrl
const response = await this.fetch('createItem', url, { if (!scriptUrl) {
...session, scriptUrl = routes.childcontrollerScript
headers: { }
...session.headers, const createItemHeaders = await this.retrieveCreateItemHeaders(scriptUrl)
[xsrfTokenName] : xsrfTokenValue const response = await this.fetch('createItem', url, createItemHeaders)
}
})
// Restore cookies // Restore cookies
cookies.forEach((cookie) => { cookies.forEach((cookie) => {
@ -247,7 +262,7 @@ export class Api extends EventEmitter {
Accept: 'application/json;odata=verbose', Accept: 'application/json;odata=verbose',
Auth: token, Auth: token,
Host: 'etjanst.stockholm.se', Host: 'etjanst.stockholm.se',
Referer: 'https://etjanst.stockholm.se/Vardnadshavare/inloggad2/hem', Referer: 'https://etjanst.stockholm.se/vardnadshavare/inloggad2/hem',
}, },
}) })
const response = await this.fetch('children', url, session) const response = await this.fetch('children', url, session)

View File

@ -54,4 +54,6 @@ export const hemPage = 'https://etjanst.stockholm.se/vardnadshavare/inloggad2/he
export const navigationControllerScript = 'https://etjanst.stockholm.se/vardnadshavare/bundles/navigationController' export const navigationControllerScript = 'https://etjanst.stockholm.se/vardnadshavare/bundles/navigationController'
export const baseEtjanst = 'https://etjanst.stockholm.se'
export const childcontrollerScript = `https://etjanst.stockholm.se/vardnadshavare/bundles/childcontroller?v=${Date.now()}` export const childcontrollerScript = `https://etjanst.stockholm.se/vardnadshavare/bundles/childcontroller?v=${Date.now()}`