{"record":{"id":"0b2a7ff44f802b22","repo":"shadow1ng/fscan","slug":"readapplicationtag-bad-tag","errorCode":null,"errorMessage":"ReadApplicationTag bad tag","messagePattern":"ReadApplicationTag bad tag","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/protocol/t125/ber/ber.go","lineNumber":164,"sourceCode":"func WriteBoolean(b bool, w io.Writer) {\n\tbb := uint8(0)\n\tif b {\n\t\tbb = uint8(0xff)\n\t}\n\tWriteUniversalTag(TAG_BOOLEAN, false, w)\n\tWriteLength(1, w)\n\tcore.WriteUInt8(bb, w)\n}\n\nfunc ReadApplicationTag(tag uint8, r io.Reader) (int, error) {\n\tbb, _ := core.ReadUInt8(r)\n\tif tag > 30 {\n\t\tif bb != (CLASS_APPL|PC_CONSTRUCT)|TAG_MASK {\n\t\t\treturn 0, errors.New(\"ReadApplicationTag invalid data\")\n\t\t}\n\t\tbb, _ := core.ReadUInt8(r)\n\t\tif bb != tag {\n\t\t\treturn 0, errors.New(\"ReadApplicationTag bad tag\")\n\t\t}\n\t} else {\n\t\tif bb != (CLASS_APPL|PC_CONSTRUCT)|(TAG_MASK&tag) {\n\t\t\treturn 0, errors.New(\"ReadApplicationTag invalid data2\")\n\t\t}\n\t}\n\treturn ReadLength(r)\n}\n\nfunc WriteApplicationTag(tag uint8, size int, w io.Writer) {\n\tif tag > 30 {\n\t\tcore.WriteUInt8((CLASS_APPL|PC_CONSTRUCT)|TAG_MASK, w)\n\t\tcore.WriteUInt8(tag, w)\n\t\tWriteLength(size, w)\n\t} else {\n\t\tcore.WriteUInt8((CLASS_APPL|PC_CONSTRUCT)|(TAG_MASK&tag), w)\n\t\tWriteLength(size, w)\n\t}","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/protocol/t125/ber/ber.go#L146-L182","documentation":"In the long tag form (tag > 30), ReadApplicationTag validates the identifier byte and then reads the actual tag number byte; if that byte does not equal the requested tag, the parsed application tag is the wrong one and this error is returned.","triggerScenarios":"ReadConnectResponse requesting a specific high application tag (e.g. 101) but the stream carries a different application tag number at that position — a different PDU arrived where CONNECT_RESPONSE was expected.","commonSituations":"Server rejecting negotiation and sending a different application-tagged PDU; desynced parsing misreading content bytes as the tag byte; nonstandard server PDU numbering.","solutions":["Log/inspect the received tag byte to see which PDU the server actually sent","Verify X.224 negotiation succeeded (check the CC result byte) before parsing CONNECT_RESPONSE","Fix any upstream desync so the tag byte is read at the correct offset","Compare the server's PDU numbering against the T.125 spec and adjust the expected tag constant if it is a known variant"],"exampleFix":"// before\nif bb != tag {\n    return 0, errors.New(\"ReadApplicationTag bad tag\")\n}\n\n// after\nif bb != tag {\n    return 0, fmt.Errorf(\"ReadApplicationTag bad tag: expected %d, got %d\", tag, bb)\n}","handlingStrategy":"try-catch","validationCode":"// peek the tag number byte and compare before full parse\nif len(buf) > pos+1 && buf[pos+1] != expectedTag {\n    return fmt.Errorf(\"server sent application tag %d, expected %d\", buf[pos+1], expectedTag)\n}","typeGuard":null,"tryCatchPattern":"n, err := ber.ReadApplicationTag(101, r)\nif err != nil {\n    if strings.Contains(err.Error(), \"bad tag\") {\n        // server sent a different PDU — inspect which one and handle\n    }\n    return err\n}","preventionTips":["Verify X.224 negotiation succeeded so the server actually sends CONNECT_RESPONSE","Log unexpected PDU tag numbers to identify server variants","Keep parsing state consistent so the tag byte is read at the right offset"],"tags":["rdp","ber","asn1","tag-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}