- **High — Unsynchronized global map can crash the server.** Relevant expressions: `var jobs = map[string]string{}`, `jobs[id] = ...`, and `status, ok := jobs[id]`. Request handlers and export goroutines access this map concurrently without synchronization. Concurrent status reads and writes can trigger a data race and the runtime fatal error `concurrent map read and map write`, terminating the process. - **High — User-controlled export name permits arbitrary file overwrite.** Relevant expression: `path := filepath.Join(s.exportDir, req.Name)` followed by `os.Create(path)`. A name such as `../../some/file` escapes `exportDir`; `os.Create` then creates or truncates any file writable by the service account. This allows an HTTP caller to overwrite configuration, application data, or other sensitive files. - **High — Arbitrary URLs create an SSRF endpoint.** Relevant expressions: `http.NewRequestWithContext(..., rawURL, nil)` and `http.DefaultClient.Do(downloadReq)`. The handler accepts URLs without restricting scheme, host, or destination. A caller can make the server request loopback, private-network, or cloud metadata endpoints and copy their responses into an export file. - **Medium — Background work uses a context canceled when the handler returns.** Relevant expression: `go s.runExport(r.Context(), id, req)`. An incoming request’s context is canceled when `ServeHTTP` returns. Since the export starts asynchronously and the handler immediately sends `202`, downloads can be canceled as soon as the response completes, making exports fail nondeterministically. - **Medium — Failed or partial exports are reported as successful.** Relevant expressions: `continue` after request/download errors, `_, _ = io.Copy(out, resp.Body)`, and the unconditional `jobs[id] = "done"`. Invalid URLs, connection failures, cancellation, and disk-write errors are ignored. Even when every download fails or the output is truncated, the status endpoint reports `done`. - **Medium — Job IDs collide for requests created in the same second.** Relevant expression: `id := strconv.FormatInt(time.Now().Unix(), 10)`. Multiple requests arriving within one second receive the same ID and overwrite the same `jobs` entry. Their goroutines can then race to publish conflicting status, so clients cannot reliably track their own export. - **Medium — Concurrent requests can corrupt the same output file.** Relevant expressions: `filepath.Join(s.exportDir, req.Name)` and `os.Create(path)`. Two requests using the same name open and truncate the same file, then write to it concurrently through separate descriptors. The resulting file can contain interleaved, missing, or unexpectedly truncated data. - **Low — Response bodies remain open for the entire export loop.** Relevant expression: `defer resp.Body.Close()` inside `for _, rawURL := range req.URLs`. Each successful response stays open until `runExport` returns. A request containing many URLs can accumulate open response bodies and connections, exhausting file descriptors or connection-pool capacity.