Enable CORS on LuCI

Hi,

Been trying to create a "web" verison of the app on https://github.com/hagaygo/OpenWRTManager

When the app runs as a "web site" , browser's CORS kicks in and OpenWRT must return allow all origin header so it can work.

Any one knows a way to cause the device to return the appropriate headers.

Only thing i found was and old post on https://gist.github.com/tomasinouk/782fb3e7a6bc0413c270e83f8bcabbea which seems to not work anymoure.

Thanks in advance.

setting ubus_cors option to 1 in /etc/config/uhttpd should do. restart the uhttpd service and see if there is a change in http response headers.

config 'uhttpd' 'main'
	option ubus_cors '1'

Hi

Thanks for your answer.

As i mentioned, that solution does not actually causes the server to send the appropriate cors header, at least not on my setup.

Can you confirm on your setup it does work?

yes, it works. what is the appropriate cors header you are looking for? it would set the Access-Control-Allow-Origin to router hostname/ip

Hi

Which version of openwrt did you test on?

The main point is to allow any origin (* as value) not only the router ip, can you supply a screenshot if the geaders you do get?

Thanks

it should work on all builds with uhttpd. i'm using snapshot build - r19805-958785508c and below headers i see when cors is enabled.

image

i believe Access-Control-Allow-Origin value is auto set based on the request headers once CORS is enabled. You dont necessarily need to set its value to *

If the web app will be hosted on the openwrt device it will work.

But in order for it to work hosted any where else the value needs to be * or at least have a configurable value. (otherwise the browser will refuse to initiate connectons to the openwrt device/s)

More info on

please let know what happens when you enable ubus_cors in config. do you get the CORS headers enabled in http response?

if its not working, pls share the /etc/config/uhttpd, /etc/openwrt_release content and a sample http post request and response headers that you are getting.

It will work wherever you host the web app, but you need to set the "Origin" request header correctly. That's your "configurable value": send the value with the request header. As @starhunter says:

This can be read in the uhttpd source code (line 153ff): the "Origin" request header is directly reflected into the "Access-Control-Allow-Origin" response header. Most notably: there is no default value, if no "Origin" request header is set, no CORS headers will be returned (line 160ff).

1 Like

I think either i am missing something in how CORS works , or i have not explained myself well.

Here is a really simple html page which performs a simple (not really working) http get to an OpenWRT url.

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>OpenWRT Access Test</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <script type="text/javascript">
        $(document).ready(function () {
            
            $("#btnClick").click(function () {
                $.get("https://192.168.200.1/ubus/", function (data) {
                    $("#result").html(data);
                    alert("Load was performed.");
                });
            });
        });
    </script>
    <button id="btnClick">Click Me!</button>
    <div id="result"></div>
</body>
</html>

When this file is hosted on a local file or any other web server which is not the host of OpenWRT the request will fail :

if i throw the file into /www directory inside openwrt it will "work" :

image

(The error is because the command is not valid , but the browser does invoke the request)

As i understand it , this behavior is a result of the response header LuCI currently return :

image

As i mentioned , if the response was * , this would work when the html file is hosted any where.

This header is a "counter measure" from any one building a site which has a javascript that generate a lot of request to third party site, this header helps site owner to either block any third party calls or allow them from specific host/ips.

This is relevant only for browser , when my app is running on android or windows this header is not relevant and the app just works.

From the conv above, you want to enable CORS in uhttpd and that you could access endpoints exposed by luci on a different host. correct us otherwise.

you please enable cors in uhttpd config, disable https redirect and then try valid "http" end point & http verb, it would work. if not pls share the complete request, response headers here for us to help you.

Of course, it is only enforced by web browsers. Also note, some web browsers wont allow you to set origin, cookie parameters in request.
you just skip setting origin and then by default those web browser/js frameworks would set Origin: null and uhttpd would still process the request if cors is enabled.

Thanks for your answer.

Correct

As mentiond before , it is already enabled , without enabling it the headers i posted are not returned in the response.

As my simple code example show, the browser refuses to invoked the request as soon as it see the response header which does not inculde any host (*) or the hosted ip/hostname of the file.

This is the code , the problem is not with the code but with the server side which doesnt return a cross origin header that would allow the code to work while hosted on other place.

While running within a browser , a http request is very limited and the code can not really change many/almost any request headers.
The url is valid and as i stated and 404 is a good response (it accepts only post) , a cross origin policy error as my screenshot showed is "bad response".