T05 · Unauthorized Access and Privilege Escalation
- Location
index.js:74- Finding
Student Grades Are Disclosed Without Authentication or Authorization
- Content
View full analysis
s.name === name); if (!student) { return null; } if (subject) { const score = student.scores[subject]; return score !== undefined ? score : null; } return student.scores; } ``` The public handler also permits caller-supplied entities to reach this function directly: ```js if (params.entities && params.entities.name) { const { name, subject } = params.entities; const scores = queryScore(name, subject); if (scores === null) { return { success: false, message: `抱歉,${name}的${subject || '该科目'}成绩暂未记录。` }; } if (subject) { return { success: true, message: `${name}的${subject}成绩是:${scores}分`, data: { name, subject, score: scores } }; } const scoreList = Object.entries(scores) .map(([sub, score]) => `${sub}: ${score}分`) .join(','); return { success: true, message: `${name}的全部成绩如下:${scoreList}`, data: { name, scores } }; } ``` ### Technical Analysis The grade lookup uses only a student name as the record selector. It does not authenticate the caller or verify that the caller is the student, an authorized guardian, or authorized school personnel. The handler trusts caller-controlled `params.entities.name` and `params.entities.subject`. If no subject is supplied, `queryScore()` returns the student's entire `scores` object. The natural-language query path has the same authorization weakness because it extracts a recognized name from the query and then performs the lookup without an access-control decision. Student names, classes, and grades are also bundled in `database/scores.json`, so anyone who can access the distributed package can read all recor ...[truncated 1370 chars]- Remediation
View remediation
