april 24, 2026 // 3 min read
hey!! :33
so i downloaded authedu.mosreg.ru with the "Save All Resources" browser extension (its the auth portal (at least authorization is one of the components) for moscow-region schools, like a sso for teachers and kids??), and found some things that broke me
package.json in the prod bundle
i open static/js/main.*.chunk.js and literally see:
https://src.cuddles.rs/lain/authedu.mosreg.ru/-/blob/master/static/js/main.cd869f4c.chunk.js#L1854
the entire package.json - all dependencies, scripts, metadata - serialized via
JSON.parse() directly into the prod bundle
probably html-webpack-inject-plugin sitting in devDependencies did this. the
author deployed and didnt notice
the author doxxed their github
Kozinchenko Evgenii <github: @inerc>
i open the profile. location: Dubai
this guy is building a russian government school portal from dubai and deanonymized himself through his own prod bundle
other finds from package.json
dev server starts on port 4242:
"start":"PORT=4242 REACT_APP_STAGE=dev node scripts/start.js"
jwt tokens (auth!) are parsed by a beta library:
jwt-decode: ^3.0.0-beta.2
react-snapshot - abandoned in 2018, last commit ~8 years ago. in prod 2025
and idea-notify: ^0.1.0 - a package at version 0.1.0 from who knows who, in a
government service
the sources arent minified
besides the bundle, Save All Resources pulled out all the source code - actions, reducers, sagas, utils. all readable!!
the typo that became a contract
// constants/index.js
export const GET_CHILDREN_REQUES = "GET_CHILDREN_REQUES";
not REQUEST, just REQUES. and its already spread everywhere - actions,
reducers, sagas. you can rename the variable, but the string
'GET_CHILDREN_REQUES' is now the official redux action type flying through the
entire system forever
setCookie math
export const setCookie = (name, value) => {
let date = new Date(new Date().getTime() + 60 * 1000 * 10); // +10 minutes
document.cookie = `...expires=${
new Date(date.getTime() * 3600).toUTCString()
}`;
};
they take a date +10 minutes, then take .getTime() (milliseconds since 1970,
currently ~1.7 * 10^12) and multiply by 3600. result is approximately year
2162. a "10 minute" cookie lives for 136 years
the condition that can never be true
if (response.status < 200 && response.status > 300 && response.status !== 404) {
throw response;
}
a number cannot simultaneously be less than 200 and greater than 300. http errors are never thrown here, ever, in principle
throw followed by return
.catch(error => {
if (...) {
throw error?.response
return // <- never
}
if (error?.response?.data) {
throw error?.response?.data;
return; // <- also never
}
just in case
setToken that sets nothing
setToken = () => {
return getCookie("aupd_token"); // takes no parameter
};
// somewhere in middleware:
const token = getCookie("aupd_token");
this.setToken(token); // passes token, discards the result
the method is called setToken. sets nothing. ignores its argument. result is
used nowhere..?
errorsNormalize - just lie to the user
if (
brief.includes(
"...Пароль не соответствует парольным политикам: содержится в словаре известных паролей.",
)
) {
return `Пароль не соответствует парольным политикам: не содержит строчную букву или прописную букву`;
}
brief is literally the java exception text from the backend. the password was
in the known passwords dictionary - but instead, tell the user it "doesn't
contain a letter". just a completely different error. why? unknown....
snowflakes forever
/**
* New Year decoration should be active from 17.12.2025 to 14.01.2026
*/
return (month === 12 && day > 16) || (month === 1 && day < 15);
comment with specific years, code without any year. snowflakes will fall every january until the end of time. the comment is already outdated lol
conclusions???
a government service for moscow-region:
- doxxes its own developer (hi dubai)
- ships the entire package.json to prod
- has a condition that is physically impossible to satisfy
- sets cookies for 136 years
- lies to users about password errors
- uses a beta lib for jwt
- contains a typo that cannot be fixed
version at time of discovery: 3.33.2.4