Block and allow specific urls in Qt (Python)
-
Hi, I'm making my first browser in PyQt. I input urls using QUrl.
I was wondering how I could make it so that I'd only allow my browser to access certain urls?I have so far blocked certain urls just by making it so that when the user presses enter and the QUrl is loaded, the program does this kind of check:
"if entered_url != "http://google.com", load QUrl(entered_url)"
But this is very simplistic and can be easily circumbended. If there's a hyperlink on the page and the user clicks on it, this block doesn't work anymore, because the signal doesn't come from entering a url in the urlbar.
I need to make it so that QWebengine is inherently incapable of loading but certain urls no matter where the signal comes from. -
It's not a Qt specific function. Firewall/refuse any port 80 requests that are not destined for 127.0.0.1
-
@Harborman said in Block and allow specific urls and IP's in Qt:
How would this work out?
Well, put allowed URLs in a https://doc.qt.io/qt-5/qset.html and before opening a URL check whether it is in this set.
-
@Harborman said in Block and allow specific urls and IP's in Qt:
How would this work out?
Lots of possibilities that depend on the precise specification and degree of security required. You could:
- Provide the user with a drop-down of allowed addresses and no ability to change them.
- Take the user-supplied URL, and inspect the QUrl::scheme(), QUrl::host(), and QUrl::port() for acceptable values (localhost, 127.0.0.1 etc.)
- Take the user-supplied URL, lookup the host() (QHostInfo) and check that the IP matches a local interface (QNetworkInterface and QHostAddress)
-
@ChrisW67 said in Block and allow specific urls and IP's in Qt:
@Harborman said in Block and allow specific urls and IP's in Qt:
How would this work out?
Lots of possibilities that depend on the precise specification and degree of security required. You could:
- Provide the user with a drop-down of allowed addresses and no ability to change them.
- Take the user-supplied URL, and inspect the QUrl::scheme(), QUrl::host(), and QUrl::port() for acceptable values (localhost, 127.0.0.1 etc.)
- Take the user-supplied URL, lookup the host() (QHostInfo) and check that the IP matches a local interface (QNetworkInterface and QHostAddress)
Sorry for replying a year late!
Anyway, I have so far blocked certain urls just by making it so that when the user presses enter and the QUrl is loaded, the program does this kind of check:
"if entered_url != "http://google.com", load QUrl(entered_url)"
But this is very simplistic and can be easily circumbended. If there's a hyperlink on the page and the user clicks on it, this block doesn't work anymore, because the signal doesn't come from entering a url in the urlbar.
I need to make it so that QWebengine is inherently incapable of loading but certain urls no matter where the signal comes from.
The latter two in your post might be helpful but not only am I working with Python, I also don't know how to do that stuff even with the documentation. -
@Harborman said in Block and allow specific urls in Qt (Python):
I need to make it so that QWebengine is inherently incapable of loading but certain urls no matter where the signal comes from.
Have a look at :
bool acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) -
@mpergand said in Block and allow specific urls in Qt (Python):
@Harborman said in Block and allow specific urls in Qt (Python):
I need to make it so that QWebengine is inherently incapable of loading but certain urls no matter where the signal comes from.
Have a look at :
bool acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame)Thank you. Here's how I got it to work. I added this new class:
class WebEnginePage(QWebEnginePage): def acceptNavigationRequest(self, url, _type, isMainFrame): if (_type == QWebEnginePage.NavigationTypeLinkClicked and url.host() != "127.0.0.1"): return False return super().acceptNavigationRequest(url, _type, isMainFrame)
And I customized my new tab function, which is the cornerstone of my tabbed browser:
def add_new_tab(self, browser, urli=None): index = self.tabs.count() browser = Browser(self) browser.setPage(WebEnginePage(self))
This works, and outside links on a website can no longer be opened by clicking on them. However, because of my messy browser, typing urls in the urlbar don't go through this new WebEnginePage class and are not subject to that check.
That part of my browser still looks like this:self.urlbar.returnPressed.connect(self.go_to_url) #press enter to load url
def go_to_url(self): url = QUrl(self.urlbar.text()).toString() if url.startswith("google") == True: self.tabs.currentWidget().setHtml(siteblocked)
Is there a simple way to implement the acceptNavigationRequest thingy to this scenario too?