fix: validate the deep-link state param before propagating it
?state= was used verbatim and ends up interpolated into a fetch URL and into
the Hugging Face parquet shard path duckdb-wasm reads. Impact is low -- it is a
client-only fetch to a public HTTPS URL, and the wasm sandbox loads no httpfs
-- but validating at the boundary is cheap and correct. Deep links now require
/^[A-Z]{2}$/ (after trim + uppercase, so ?state=az still works) and fall back
to the state selector with a warning when they do not match.
This commit is contained in:
+16
-2
@@ -6,9 +6,14 @@ import ChartPanel from './components/ChartPanel.jsx'
|
||||
import Footer from './components/Footer.jsx'
|
||||
import { fetchDistrictEstimates } from './hooks/useApi.js'
|
||||
|
||||
// Two-letter USPS state code. The deep-link value flows into API request URLs
|
||||
// and into the Hugging Face parquet shard path duckdb-wasm reads, so it gets
|
||||
// validated here at the boundary rather than propagated verbatim.
|
||||
const STATE_CODE_PATTERN = /^[A-Z]{2}$/
|
||||
|
||||
/**
|
||||
* CRDC Arrests API Demo App — main router.
|
||||
* Flow: state → district search (with interesting suggestions) → loading animation → 6 charts
|
||||
* Flow: state → district search (with interesting suggestions) → loading animation → charts
|
||||
*/
|
||||
export default function App() {
|
||||
const [step, setStep] = useState('state') // 'state' | 'search' | 'loading' | 'results'
|
||||
@@ -19,7 +24,16 @@ export default function App() {
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const leaid = params.get('leaid')
|
||||
const stateParam = params.get('state')
|
||||
const rawState = params.get('state')
|
||||
const stateParam = rawState ? rawState.trim().toUpperCase() : null
|
||||
|
||||
if (rawState && !STATE_CODE_PATTERN.test(stateParam)) {
|
||||
// Malformed deep link — drop it and start at the state selector rather
|
||||
// than passing an arbitrary string into fetch URLs and shard paths.
|
||||
console.warn('Ignoring deep link: `state` is not a two-letter state code.')
|
||||
return
|
||||
}
|
||||
|
||||
if (leaid && stateParam) {
|
||||
// Deep link (including browser back/forward landing on this URL): resolve
|
||||
// the district name via a real estimates row, keyed by LEAID. The previous
|
||||
|
||||
Reference in New Issue
Block a user