T09 · Insecure Skill Coding Practices
- Location
scripts/recognize_doc.py:66- Finding
OCR Credentials Stored in Plaintext with Insufficient Access Controls
- Content
View full analysis
Vulnerability Details
File Location:
scripts/recognize_doc.py, lines 66–73; related credential handling at lines 371–376 and 383–386
Vulnerability Type: Plaintext sensitive-data storage and credential disclosure
Risk Level: MediumVulnerable Code
python def save_config(config: dict): """保存配置文件""" config_path = Path(__file__).parent.parent / "config.json" with open(config_path, 'w', encoding='utf-8') as f: json.dump(config, f, indent=2, ensure_ascii=False)Related credential collection and display logic:
python netocr_key = input("netocr_key: ").strip() netocr_secret = input("netocr_secret: ").strip() config = { "netocr_key": netocr_key, "netocr_secret": netocr_secret } save_config(config)python print(f" OCR Key: {config.get('netocr_key', '(未设置)')}") print(f" OCR Secret: {'*' * 8 if config.get('netocr_secret') else '(未设置)'}")Technical Analysis
The configuration routine stores both
netocr_keyandnetocr_secretas unencrypted JSON in the predictable project-root fileconfig.json. The file is opened using the process's default permission behavior, subject to the currentumask, rather than being explicitly created with owner-only permissions.The secret is also collected through
input(), which echoes entered characters to the terminal. This can expose it through shoulder surfing, terminal recording, remote-session logging, or screen capture. Although--list-configmasks the secret, it prints the complete OCR key.The bundled
config.jsoncontained empty values during the audit, so no active credential was present in the reviewed artifact. The vulnerability arises after a user runs the documented configuration workflow.The separately flagged Base64 and network behavior is consistent with the declared cloud OCR functionality: complete document bytes are Base64-encoded and sent with the credentials over HTTPS t ...[truncated 1442 chars]
- Remediation
View remediation
Remediation Suggestions
- Store credentials in an operating-system credential manager or secret-management service rather than in the Skill directory.
- If file-based storage is unavoidable, create the file with owner-only permissions such as mode
0600, verify its ownership and permissions before reading it, and reject insecure configurations. - Collect
netocr_secretusinggetpass.getpass()so that it is not echoed to the terminal. - Mask both the OCR key and secret in
--list-config; reveal only a minimal suffix if identification is required. - Exclude
config.jsonfrom source control, backups intended for sharing, Skill packaging, logs, and diagnostic bundles. Provide a separate placeholder such asconfig.example.json. - Support environment variables or injected runtime secrets for automated deployments.
- Document that complete source documents and credentials are transmitted to the third-party NetOCR service, including the destination, billing implications, retention considerations, and required user consent.
- Rotate any credentials if a populated configuration file has previously been published, shared, backed up insecurely, or exposed to unauthorized users.
