bitracker
"My School" and package.json in prod

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

src??

here!