Skip to content

IRL - Add Rule for DOM-XSS issues #91

@noelsaw1

Description

@noelsaw1
  • Version 1.x

  • Version 2.x

Run this to find potential DOM-XSS issues:

cd /Users/noelsaw/Local\ Sites/neochrome-timesheets/app/public/wp-content/plugins/Hypercart-Server-Monitor-MKII

Find HTML string concatenation with variables

grep -rn "html += ['"]<[^>]*>['"] *+ *[a-zA-Z]" src/Admin/views/

Find .html() with variables

grep -rn ".html(.[a-zA-Z_][a-zA-Z0-9_].*)" src/Admin/views/

Find innerHTML assignments

grep -rn "innerHTML.*=" src/


🔍 2. Can WordPress Code Checker Catch This?

Short Answer: No, not easily.

This is a DOM-based XSS vulnerability in JavaScript, not PHP. WordPress Coding Standards (WPCS) and PHP_CodeSniffer primarily focus on server-side PHP code.

Why It's Hard to Detect:

1. Language Boundary

// WPCS can check this (PHP):
echo '<div>' . $user_input . '</div>';  // ❌ WPCS will flag this

// But NOT this (JavaScript in PHP file):
html += '<div>' + userInput + '</div>';  // ⚠️ WPCS won't flag this

WPCS doesn't parse JavaScript semantics - it sees the JS as a string literal.

2. Context-Specific

The vulnerability is in how JavaScript builds HTML strings, which requires understanding:

  • Variable scope (is data.warnings[i] user-controlled?)
  • Data flow (where does score.label come from?)
  • DOM manipulation (is this inserted via .html() or .text()?)

Static analysis tools struggle with this.


What WPCS CAN Detect:

Server-side XSS in PHP:

// WPCS will flag these:
echo $user_input;                    // Missing escaping
echo '<div>' . $_GET['name'] . '</div>';  // Unescaped GET parameter

Missing escaping functions:

// WPCS checks for:
esc_html()
esc_attr()
esc_url()
wp_kses()

Grep Patterns for DOM-XSS Detection:

While not perfect, you can use grep patterns to flag suspicious code for manual review:

Pattern 1: HTML String Concatenation with Variables

# Find JavaScript HTML building with unescaped variables
grep -rn "html += '<[^>]*>' + [a-zA-Z]" src/Admin/views/

# Output:
# tab-manual-test.php:124: html += '<li>' + data.warnings[i] + '</li>';

Pattern 2: jQuery .html() with Concatenation

# Find .html() calls with string concatenation
grep -rn "\.html(.*\+.*)" src/

# Output:
# tab-manual-test.php:191: $results.html(html).show();

Pattern 3: Direct Variable Insertion in HTML Strings

# Find patterns like: '<tag>' + variable + '</tag>'
grep -rn "'<[^>]*>' *+ *[a-zA-Z_]" src/Admin/views/

# More specific for closing tags:
grep -rn "+ *[a-zA-Z_][a-zA-Z0-9_.]* *+ *'</" src/

Pattern 4: Response Data Used in HTML

# Find response.data or data. used in HTML building
grep -rn "html += .*\(response\.data\|data\.\)" src/

Recommended Detection Strategy:

1. Manual Code Review Checklist

Create a checklist for JavaScript files:

  • All user/server data escaped before HTML insertion?
  • Using .text() instead of .html() where possible?
  • HTML string building uses escaping function?
  • No innerHTML with unescaped data?

2. ESLint Rules (Better than grep)

Use ESLint with security plugins:

// .eslintrc.json
{
  "plugins": ["no-unsanitized"],
  "rules": {
    "no-unsanitized/method": "error",
    "no-unsanitized/property": "error"
  }
}

This will flag:

element.innerHTML = userInput;  // ❌ Flagged
$div.html(userInput);           // ❌ Flagged

3. Custom PHPCS Sniff (Advanced)

You could write a custom PHPCS sniff to detect JavaScript patterns in PHP files:

// Custom sniff to detect unescaped JS HTML building
class DomXssSniff implements Sniff {
    public function process(File $phpcsFile, $stackPtr) {
        // Look for: html += '<tag>' + variable
        // Flag for manual review
    }
}

But this is complex and has high false-positive rates.


Practical Grep Command for Your Codebase:

# Run this to find potential DOM-XSS issues:
cd /Users/noelsaw/Local\ Sites/neochrome-timesheets/app/public/wp-content/plugins/Hypercart-Server-Monitor-MKII

# Find HTML string concatenation with variables
grep -rn "html += ['\"]<[^>]*>['\"] *\+ *[a-zA-Z]" src/Admin/views/

# Find .html() with variables
grep -rn "\.html(.*[a-zA-Z_][a-zA-Z0-9_]*.*)" src/Admin/views/

# Find innerHTML assignments
grep -rn "innerHTML.*=" src/

Summary Table:

Detection Method Can Detect DOM-XSS? Effort False Positives
WPCS (PHP_CodeSniffer) ❌ No Low N/A
Grep Patterns ⚠️ Partial Low High
ESLint + Security Plugins ✅ Yes Medium Medium
Manual Code Review ✅ Yes High None
Custom PHPCS Sniff ⚠️ Partial Very High High

🎯 Recommendation:

  1. Use grep patterns for quick scanning (flags for manual review)
  2. Add ESLint to your build process for JavaScript files
  3. Manual code review for all JavaScript that builds HTML
  4. Security checklist in your development workflow

For this specific codebase: The grep patterns above would have flagged the vulnerable lines in tab-manual-test.php for manual review.


Would you like me to:

  1. Create an ESLint configuration for the project?
  2. Write a shell script with comprehensive grep patterns?
  3. Document the security review checklist for future development?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions