T09 · Insecure Skill Coding Practices
- Location
scripts/htaccess.py:210- Finding
Apache Configuration and Regular Expression Injection Through Unsanitized Generator Inputs
- Content
View full analysis
Vulnerability Details
File Location:
scripts/htaccess.py, lines 210–248
Vulnerability Type: Apache configuration injection and regular expression injection
Risk Level: HighVulnerable Code
python if args.cors: mode = args.cors if mode in CORS_RULES: rules = CORS_RULES[mode] if args.domain and mode == "specific": rules = [r.replace("{domain}", args.domain.replace(".", "\\.")) for r in rules] sections.append(rules) if args.protect: for name in args.protect: if name in PROTECTION_RULES: rules = PROTECTION_RULES[name] if args.domain: rules = [r.replace("{domain}", args.domain.replace(".", "\\.")) for r in rules] sections.append(rules) else: print(f"Warning: Unknown protection '{name}'. Available: {', '.join(PROTECTION_RULES.keys())}", file=sys.stderr) if args.redirects: redirect_lines = ["# Redirects"] for spec in args.redirects: parts = spec.split("->") if len(parts) == 2: from_path = parts[0].strip() to_url = parts[1].strip() status = "301" redirect_lines.append(f"Redirect {status} {from_path} {to_url}") sections.append(redirect_lines)The resulting configuration is written at lines 261–263:
python if args.output: with open(args.output, 'w') as f: f.write(output + "\n")Technical Analysis
The
--domainargument is inserted into Apache regular expressions after escaping only periods. Other regular-expression metacharacters, quotes, whitespace, carriage returns, and newline characters remain accepted. Consequently, an attacker-controlled domain can change the meaning of domain-specific CORS or hotlink-protection expressions. Control characters can also terminate the intended directive and introduce additional Apache configuratio ...[truncated 2103 chars]- Remediation
View remediation
Remediation Suggestions
- Validate
--domainas a canonical DNS hostname rather than treating it as an arbitrary regular-expression fragment:- Reject carriage returns, newlines, quotes, whitespace, slashes, and control characters.
- Enforce valid hostname label and total-length limits.
- Normalize internationalized domains to an explicitly supported ASCII representation if required.
- Use
re.escape()when inserting a validated hostname into an Apache regular expression instead of escaping only periods. - Validate redirect source paths:
- Require a local absolute path beginning with
/. - Reject whitespace, control characters, and Apache configuration delimiters.
- Require a local absolute path beginning with
- Validate redirect destinations against an explicit policy:
- Permit only local absolute paths or well-formed
httpandhttpsURLs. - Optionally restrict external destinations to an allowlist.
- Reject embedded credentials, control characters, and unsupported schemes.
- Permit only local absolute paths or well-formed
- Apply a final safety check to every generated line and reject any interpolated value containing
\r,\n, or other non-printable characters. - Prefer structured generator functions that validate each semantic field before rendering configuration text.
- Add tests covering newline injection, carriage-return injection, quotes, spaces, regex alternation, grouping, wildcards, malformed hostnames, unsupported URL schemes, and multiple
->delimiters. - Write to a temporary file, validate the complete generated configuration with Apache tooling where available, and replace the destination atomically only after successful validation.
- Validate
