Skip to content

🔒 [security fix] Implement URL encoding for mailto: and tel: links#24

Open
SmolSoftBoi wants to merge 2 commits into
mainfrom
security-fix-uri-encoding-16311954826983525945
Open

🔒 [security fix] Implement URL encoding for mailto: and tel: links#24
SmolSoftBoi wants to merge 2 commits into
mainfrom
security-fix-uri-encoding-16311954826983525945

Conversation

@SmolSoftBoi

@SmolSoftBoi SmolSoftBoi commented May 9, 2026

Copy link
Copy Markdown
Owner

The vulnerability involved missing URL encoding when placing dynamic content into mailto: link parameters in SDSComXSL.xsl. This could lead to URI injection or broken links if fields like the document title or product number contained special characters (e.g., spaces, ampersands).

To address this, I have:

  1. Applied fn:encode-for-uri() to the dynamic parts of all mailto: links, including the email address and the subject query parameter.
  2. Applied fn:encode-for-uri() to tel: links for consistency and URI safety.
  3. Fixed a separate bug in the CompanyUrl link where the href attribute was incorrectly set to a literal string instead of using an Attribute Value Template.

All changes were verified to be syntactically correct and follow XSLT 3.0 best practices.


PR created automatically by Jules for task 16311954826983525945 started by @SmolSoftBoi

Summary by Sourcery

Apply URI encoding to dynamic contact links to harden against malformed or unsafe URLs.

Bug Fixes:

  • Encode dynamic mailto email addresses and subject parameters to prevent URI injection and handling issues.
  • Encode tel links’ phone numbers to ensure safe and well-formed telephone URIs.
  • Fix CompanyUrl anchor to use the dynamic URL value instead of a hard-coded literal href.

- Use `fn:encode-for-uri()` for dynamic content in `mailto:` links (email addresses and subject query parameters).
- Use `fn:encode-for-uri()` for dynamic content in `tel:` links.
- Fix bug in `CompanyUrl` link where it was missing Attribute Value Template curly braces.

🎯 What: Missing URL encoding in URI schemes.
⚠️ Risk: Potential for URI injection or broken links if dynamic content contains special characters.
🛡️ Solution: Applied standard XSLT `fn:encode-for-uri()` function to dynamic components of URIs.

Co-authored-by: SmolSoftBoi <491681+SmolSoftBoi@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 9, 2026 22:46
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

This comment was marked as low quality.

@sourcery-ai

sourcery-ai Bot commented May 9, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds URI encoding to dynamic mailto: and tel: links in SDSComXSL.xsl and fixes an incorrectly hard-coded CompanyUrl href to use the XSLT value, improving security and correctness of generated links.

Flow diagram for URI-encoding dynamic mailto and tel links

flowchart TD
    A[SDS XML data
    - Email
    - EmailCompetentPerson
    - CompanyUrl
    - EmergencyPhone No
    - Title
    - ProductNo] --> B[XSLT template SDSComXSL]

    B --> C1[Apply fn:encode-for-uri to Email]
    B --> C2[Apply fn:encode-for-uri to EmailCompetentPerson]
    B --> C3[Apply fn:encode-for-uri to Title]
    B --> C4[Apply fn:encode-for-uri to ProductNo]
    B --> C5[Apply fn:encode-for-uri to EmergencyPhone No]
    B --> C6[Use CompanyUrl as AVT in href]

    C1 --> D1[Build mailto href<br/>mailto:&#123;encoded Email&#125;]
    C2 --> D2[Build mailto href<br/>mailto:&#123;encoded EmailCompetentPerson&#125;]
    C3 --> D1
    C4 --> D1
    C3 --> D2
    C4 --> D2
    C5 --> D3[Build tel href<br/>tel:&#123;encoded No&#125;]
    C6 --> D4[Build http/https href<br/>&#123;CompanyUrl&#125;]

    D1 --> E[HTML a elements with
    encoded mailto links
    including subject with
    encoded Title and ProductNo]
    D2 --> E
    D3 --> F[HTML a elements with
    encoded tel links]
    D4 --> G[HTML a element with
    correct CompanyUrl href]

    E --> H[Browser renders safe mailto links]
    F --> H
    G --> H
Loading

File-Level Changes

Change Details Files
Apply URI encoding to all dynamic mailto: links to prevent URI injection and handle special characters safely.
  • Wrap the dynamic email address value in fn:encode-for-uri(.) when used in mailto: hrefs.
  • Wrap the dynamic Email and EmailCompetentPerson fields in fn:encode-for-uri() in their respective mailto: hrefs.
  • Wrap the dynamic $Title and ProductNo values in fn:encode-for-uri() when used inside the subject query parameter of mailto: links.
SDSComXSL.xsl
Apply URI encoding to tel: links to ensure phone numbers are URI-safe.
  • Wrap the dynamic EmergencyPhone/No value in fn:encode-for-uri() when composing tel: hrefs.
SDSComXSL.xsl
Fix CompanyUrl anchor to use an Attribute Value Template instead of a hard-coded string in the href attribute.
  • Change the CompanyUrl anchor href from a literal "CompanyUrl" string to an AVT using {CompanyUrl} so the generated link points to the actual company URL value.
SDSComXSL.xsl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • For the mailto: links, consider encoding the subject as a single value (e.g. subject={fn:encode-for-uri(concat($Title, ' ', ProductNo))}) rather than mixing a literal %20 with separately encoded pieces to avoid awkward composition and potential double-encoding issues if this evolves.
  • You’re applying fn:encode-for-uri() to the entire email address and phone number; while this is safe, it also encodes characters like @ and + that are valid in the mailto:/tel: schemes—if readability or interoperability with some clients matters, you might prefer encoding only the query parameters and leaving the address/number unencoded.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- For the `mailto:` links, consider encoding the subject as a single value (e.g. `subject={fn:encode-for-uri(concat($Title, ' ', ProductNo))}`) rather than mixing a literal `%20` with separately encoded pieces to avoid awkward composition and potential double-encoding issues if this evolves.
- You’re applying `fn:encode-for-uri()` to the entire email address and phone number; while this is safe, it also encodes characters like `@` and `+` that are valid in the `mailto:`/`tel:` schemes—if readability or interoperability with some clients matters, you might prefer encoding only the query parameters and leaving the address/number unencoded.

## Individual Comments

### Comment 1
<location path="SDSComXSL.xsl" line_range="466" />
<code_context>
                             <xsl:for-each select="EmergencyPhone">
                                 <dt class="col-4">
-                                    <a href="tel:{No}"><xsl:value-of select="No"/></a>
+                                    <a href="tel:{fn:encode-for-uri(No)}"><xsl:value-of select="No"/></a>
                                 </dt>
                                 <dd class="col-8">
</code_context>
<issue_to_address>
**issue (bug_risk):** Encoding the entire phone number for a `tel:` URI can break valid numbers (e.g., leading `+`).

`fn:encode-for-uri` will turn `+` into `%2B`, but `tel:` URIs expect a literal leading `+` (and some clients may not handle the encoded form). Consider leaving the number unencoded and only normalizing/stripping spaces or formatting characters instead of encoding the entire value.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread SDSComXSL.xsl
<xsl:for-each select="EmergencyPhone">
<dt class="col-4">
<a href="tel:{No}"><xsl:value-of select="No"/></a>
<a href="tel:{fn:encode-for-uri(No)}"><xsl:value-of select="No"/></a>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Encoding the entire phone number for a tel: URI can break valid numbers (e.g., leading +).

fn:encode-for-uri will turn + into %2B, but tel: URIs expect a literal leading + (and some clients may not handle the encoded form). Consider leaving the number unencoded and only normalizing/stripping spaces or formatting characters instead of encoding the entire value.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0eb86e177d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread SDSComXSL.xsl
<xsl:for-each select="EmergencyPhone">
<dt class="col-4">
<a href="tel:{No}"><xsl:value-of select="No"/></a>
<a href="tel:{fn:encode-for-uri(No)}"><xsl:value-of select="No"/></a>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not percent-encode the full tel subscriber

Encoding No with fn:encode-for-uri() turns delimiter characters like +, ;, =, and ? into %2B, %3B, etc., but these delimiters are significant in tel: URIs (for global numbers and parameters such as extensions). For emergency numbers that include a leading + or URI parameters, the generated link can become non-conformant and may not dial correctly in some clients.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens generated mailto: and tel: links in the main SDS HTML XSLT by URL-encoding dynamic URI components, and fixes the CompanyUrl anchor so it actually uses the XML-provided URL.

Changes:

  • Apply fn:encode-for-uri() to dynamic pieces of mailto: links (address + subject parts).
  • Apply fn:encode-for-uri() to tel: links.
  • Fix CompanyUrl anchor href to use an Attribute Value Template ({CompanyUrl}).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread SDSComXSL.xsl
</dt>
<dd class="col-8">
<a href="CompanyUrl" target="_blank"><xsl:value-of select="CompanyUrl"/></a>
<a href="{CompanyUrl}" target="_blank"><xsl:value-of select="CompanyUrl"/></a>
Comment thread SDSComXSL.xsl
<br/>
</xsl:if>
<a href="mailto:{.}?subject={$Title}%20{ProductNo}"><xsl:value-of select="."/></a>
<a href="mailto:{fn:encode-for-uri(.)}?subject={fn:encode-for-uri($Title)}%20{fn:encode-for-uri(ProductNo)}"><xsl:value-of select="."/></a>
Comment thread SDSComXSL.xsl
</dt>
<dd class="col-8">
<a href="mailto:{Email}?subject={$Title}%20{ProductNo}"><xsl:value-of select="Email"/></a>
<a href="mailto:{fn:encode-for-uri(Email)}?subject={fn:encode-for-uri($Title)}%20{fn:encode-for-uri(ProductNo)}"><xsl:value-of select="Email"/></a>
Comment thread SDSComXSL.xsl
</dt>
<dd class="col-8">
<a href="mailto:{EmailCompetentPerson}?subject={$Title}%20{ProductNo}"><xsl:value-of select="EmailCompetentPerson"/></a>
<a href="mailto:{fn:encode-for-uri(EmailCompetentPerson)}?subject={fn:encode-for-uri($Title)}%20{fn:encode-for-uri(ProductNo)}"><xsl:value-of select="EmailCompetentPerson"/></a>
Comment thread SDSComXSL.xsl
<xsl:for-each select="EmergencyPhone">
<dt class="col-4">
<a href="tel:{No}"><xsl:value-of select="No"/></a>
<a href="tel:{fn:encode-for-uri(No)}"><xsl:value-of select="No"/></a>

@charliecreates charliecreates Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking feedback

  1. tel: links should not URI-encode the entire subscriber. fn:encode-for-uri(No) encodes structural delimiters like +, ;, =, and ?, which can break valid global numbers and parameters (for example +... or ;ext=) in RFC 3966 — SDSComXSL.xsl#L466

If you'd like me to apply a fix for this, reply with please fix 1.

Comment thread SDSComXSL.xsl
<xsl:for-each select="EmergencyPhone">
<dt class="col-4">
<a href="tel:{No}"><xsl:value-of select="No"/></a>
<a href="tel:{fn:encode-for-uri(No)}"><xsl:value-of select="No"/></a>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tel: URIs are structured, so encoding the entire subscriber with fn:encode-for-uri(No) is risky here: it percent-encodes delimiter characters that RFC 3966 expects to stay literal (+, ;, =, ?). That can break valid forms like global numbers (+...) and parameters (;ext=, ;phone-context=).

Suggested fix: normalize/validate No, then compose the tel: URI structurally without full URI-component encoding; only encode parameter values when needed.

- Use `fn:encode-for-uri()` for dynamic content in `mailto:` links (email addresses and subject query parameters).
- Use `fn:encode-for-uri()` for dynamic content in `tel:` links.
- Fix bug in `CompanyUrl` link where it was missing Attribute Value Template curly braces.
- Update GitHub Actions workflow to use `actions/checkout@v4` and `actions/setup-node@v4` with `cache: 'yarn'`.

🎯 What: Missing URL encoding in URI schemes and incorrect CI configuration.
⚠️ Risk: Potential for URI injection or broken links. CI pipeline failing due to incorrect cache settings and deprecated actions.
🛡️ Solution: Applied standard XSLT `fn:encode-for-uri()` function, corrected Attribute Value Templates, and updated CI workflow.

Co-authored-by: SmolSoftBoi <491681+SmolSoftBoi@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants