Laden...

Flurl.Http, C#, PHP, MySQL und das Thema Sicherheit

Erstellt von LittleTester vor 2 Jahren Letzter Beitrag vor 2 Jahren 687 Views
L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren
Flurl.Http, C#, PHP, MySQL und das Thema Sicherheit

Hallo liebe Gemeinschaft,

zunächst: Mir wurde in diesem Thread das das Erstellen einer Web-API mit ASP.NET Core empfohlen und ein Tutorial verlinkt. Ich habe es versucht nach zu bauen und absolut nichts verstanden. Ich schätze ich bin noch nicht so weit.

Ich wollte mich dann mit dem Thema WebClient befassen, aber irgendwie hatte ich immer nur Beispiele mit $_GET gefunden, woran ich mich ziemlich störte. Zudem habe ich sehr viele Daten zu übertragen. Das wäre über die URL totaler Quatsch gewesen, (wenn das überhaupt gegangen wäre).

Ich habe dann die Libray Fluent HTTP entdeckt. Genau mein Geschmack. Total einfach. Ruckzuck war der entsprechende Code geschrieben. Sieht im groben so aus:


using Flurl.Http;
        string securityKey = "$2y$10$GRcTbg!q2fj/7fSMgz0Eef4uFrbAFM8jILV2b((4bK323OFl57o1a";

var responseString = await "https://example.tld/update_db.php"
                .PostUrlEncodedAsync(new {
                    securityKey = securityKey,
                    computerName = computerName,
                    computerModel = computerModel,
                    computerType = computerType,
                    computerSerial = computerSerial
                })
                .ReceiveString();

Das PHP-Script sieht so aus:


if(isset($_POST['securityKey']) == "$2y$10$GRcTbg!q2fj/7fSMgz0Eef4uFrbAFM8jILV2b((4bK323OFl57o1a"){
# Datenfankverbindung herstellen
$db_connect = db_connect();

$db_update = "Update db_computer ...

Nun sind wir aber mal ehrlich. Ja, das funktioniert, aber glücklich kann man damit nicht sein. Wirklich sicher ist das mit dem "securityKey" ja nicht, oder? Außerdem steht er noch hardcoded im PHP-File wobei... naja, in der config-Datei zum Herstellen der Datenbankverbindung stehen die Daten ja auch im Klartext ❔
Außerdem bekomme ich keine Rückmeldung vom PHP-Script wenn was schief läuft. Auch nicht so toll.

Daher meine Fragen:

  1. Kann man es mit Fluent HTTP anstellen, dass man im C#-Programm (oder sonnst irgendwie) eine Rückmeldung bekommt oder wird der String einfach nur abgeschickt und der Rest ist der Libray egal? Mein Englisch hapert leider etwas, so dass ich auf der Seite nicht mit allem zurecht komme.

  2. Kann man die PHP-Datei sicherer machen, so dass nicht gerade jeder daher gelaufene Bot oder ein zufällig darüber stolperndes Script Kiddy Unfug anstellen kann?

Nur Klarstellung:
Ich will mich schon auch noch mit Rest-API und / oder SOAP näher befassen, aber mir wäre es wirklich wichtig erstmal ein Projekt zu Ende zu bringen. (Ich habe in den vielen Jahren so viele begonnen und nie zu Ende gebracht, bzw. wieder aufgehört weil es irgendwo klemmte. Das hier ist das erste auf der Zielgeraden und ich möchte es nicht kurz vor knapp wieder abbrechen, weils mal wieder Probleme gibt. Das demotiviert dann auch jedes mal). Danach will ich es komplett neu entwickeln auf einer völlig neuen Basis, beispielsweise mit Symfony oder Laravel als PHP-Framework.

Edit: Ich habe das Thema ganz bewusst nicht in der Rubrik Code-Reviews gepostet, weil es nicht um ein Review geht. Vielmehr habe ich ja Fragen zur Thematik. Ich schreib das nur, weil ich in letzter Zeit ein Händchen dafür hatte in der falschen Rubrik zu posten.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

309 Beiträge seit 2020
vor 2 Jahren

Hallo liebe Gemeinschaft,

zunächst: Mir wurde in
>
das das Erstellen einer
>
empfohlen und ein Tutorial verlinkt. Ich habe es versucht nach zu bauen und absolut nichts verstanden. Ich schätze ich bin noch nicht so weit.

Damit solltest du dir deinen Endpunkt bauen, dann kannst du auf das PHP Skript verzichten. Das würde vieles einfacher machen (Authentifizierung, etc.).

Dass der Token im PHP Skript steht, sehe ich gar nicht als Problem, das hat ja WordPress auch. Muss halt nur dein PHP Code sicher sein. Wenn du das aber auch in der Assembly speichern willst, dann ist es natürlich offen.
Und bei Sicherheit steht dein PHP Skript im Mittelpunkt, weiß nicht ob du hier damit richtig bist 😁

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Ja, ich hatte mir überlegt, ob das eher ein Thema fürs PHP-Forum wäre, aber das PHP-Script wird ja aus C# heraus aufgerufen und mit Daten gefüttert. Daher denke ich muss auch alles von der Anwendung kommen? Zudem möchte ich die Antwort des PHP-Scripts in der C#-Anwendung sehen. Das SQL-Statement ist natürlich mittels Prepared Statement abgesichert.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

2.078 Beiträge seit 2012
vor 2 Jahren

Das sind halt alles Dinge, die mit den Frameworks ASP.NET und Refit quasi keine Arbeit mehr sind 🙂
Für ASP.NET Core gibt's in VisualStudio entsprechende Templates, da kannst Du eines erstellen, was dann auch direkt einen Test-Endpunkt hat.

Und für Refit gibt's ne gute kleine Doku - leider nur mit async.
Du kannst natürlich auch ohne Refit arbeiten, musst den ganzen Client-Kram dann aber selber machen.

16.806 Beiträge seit 2008
vor 2 Jahren

Bei Security Themen unbedingt die Grundlagen lernen, sonst wirst Du die Konzepte - wie hier - nicht verstehen und am Ende unsicheren oder lückenhaften Code produzieren.
Da führt leider absolut kein Weg dran vorbei.

Wirklich sicher ist das mit dem "securityKey" ja nicht, oder?

Doch; hier kommen die Grundlagen zu HTTP bzw besser gesagt HTTPS zu tragen: alle Body-Inhalte werden bei HTTPS verschlüsselt.
Das bedeutet, dass der Body bei POST prinzipiell sicher ist, sofern HTTPS verwendet wird. Eine Übertragung als URL Parameter ist jedoch niemals sicher, da er auch bei HTTPS nicht verschlüsselt wird.

Daher ist die Übertragung des Keys im Body bei HTTPS kein Problem; das ist sogar prinzipiell ein extrem weit verbreitetes, weil simpel und sicher, Vorhaben.

Ja, man sieht APIs, die den Key auch in der URL akzeptieren; da kann man nur mit dem Kopf schütteln.

Und für Refit gibt's ne gute kleine Doku - leider nur mit async.

Und das ist auch gut so 🙂
Es sollten viel mehr Libs asynchronen Code erzwingen.

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Danke für eure Antworten und die Aufklärung / Hinweise.

Kann mir nun noch jemand sagen, wie ich vom PHP eine Rückmeldung in C# verarbeiten kann? Wenn man nach "C# PHP" und vergleichbaren Suchbegriffen sucht findet man halt immer Beispiele und Anfragen, wie man von C# etwas nach PHP schicken kann, aber nicht umgekehrt. Wenn das mit Flurl zu bewerkstelligen ist wäre das natürlich echt Klasse. Ist mir ne sympathische Libray, weil sie so wenig Code erfordert und damit auch leicht zu verstehen ist 😄.

Zum Ablauf des Programms:

Im Webinterface trage ich die Seriennummer (und einige andere Dinge, wie beispielsweise Rechnungsdatum und so) des Rechners in ein Formular ein und schicke das in die Datenbank.
Das C# Tool soll dann die Inventardaten liefern und orientiert sich an der Seriennummer. Was nun aber, wenn es in der Datenbank die Seriennummer gar nicht gibt? Zumindest dafür braucht es eine Rückmeldung.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

16.806 Beiträge seit 2008
vor 2 Jahren

Austauschformate von HTTP APIs sind alle standardisiert, sowohl die Antwort-Codes, Antwort-Strukturen wie auch in gewisserweise Inhalte.
Siehe What is REST (wirst nen paar Tage brauchen, um alles zu lesen)

REST Principles and Architectural Constraints
How to design a REST API
REST API Naming Conventions and Best Practices
HTTP Methods – REST API Verbs
HTTP Status Codes
Idempotent REST APIs
Richardson Maturity Model

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Komplex Thematik und alles in englisch. Mach mich nicht unglücklich 😭

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

16.806 Beiträge seit 2008
vor 2 Jahren

Ja, die Web-Welt ist verglichen mit der Desktop-Welt durchaus komplex. Man muss bei Web-Anwendungen auch anders programmieren und anders denken als bei einer Desktop-Anwendung. Viele verschiedene Technologien, die zusammen interargieren. Wirkt viel, ist durchaus nicht wenig - aber wenn man einen roten Pfad hat, dann gehts eigentlich.
API Design ist ein großes Thema; aber Gott sei Dank haben hier viele schlaue Menschen gute Standards geschaffen, die auch beachtet werden sollten. Daher kann man sich da gut orientieren; und die meisten Frameworks beachten das auch, sodass man hier durchaus viel geschenkt bekommt (ASP.NET macht das zum Beispiel sehr gut). Beachtet man das nicht, dann wird schnell gegen Inkompatibilitäten rennen und Zeugs selbst programmieren müssen, das ansonsten hätte geschenkt bekommen.

Wenn man das als Entwickler gut im Griff hat, dann merkt man auch recht schnell ob fremde APIs von jemanden gemacht wurden, der weiß was er tut - oder von nem Bastler 😉

Und Englisch....die IT Welt und besonders die Welt ist ziemlich Englisch-only.
Gibt nur wenige gute Quellen auf Deutsch. Zumindest Englisch lesen sollte man als Entwickler wirklich können, sonst wirds bei vielen Themen wirklich schwer.

309 Beiträge seit 2020
vor 2 Jahren

Du musst doch eigentlich nur das Tutorial: Erstellen einer Web-API mit ASP.NET Core
verfolgen und das ToDo-Modell entsprechend anpassen, dann kannst du alles 1:1 übernehmen:



    public class Rechner
    {
        public long Id { get; set; }
        public string Seriennummer { get; set; }
        public DateTimeOffset Rechnungsdatum { get; set; }
    }


Und mit der GET Methode lieferst du deine Antwort aus:


// GET: api/TodoItems/5
[HttpGet("{id}")]
public async Task<ActionResult<Rechner>> GetRechner(string Seriennummer)
{
    var rechner = await _context.TodoItems.FindAsync(Seriennummer);

    if (rechner == null)
    {
        return NotFound();
    }

    return rechner;
}

16.806 Beiträge seit 2008
vor 2 Jahren

Der Parameter-Name muss der Route-Variable entsprechen (außer man will Query Parameter, hier wohl nicht der Fall)


[HttpGet("{seriennummer}")]
public async Task<ActionResult<Rechner>> GetRechner(string seriennummer)

Und die Rückgabe müsste sein


    return Ok(rechner);
}

D
152 Beiträge seit 2013
vor 2 Jahren

Ab ASP.NET Core 2.1 ist die Verwendung von Ok(...) nicht mehr notwendig.
Rückgabetypen für Controlleraktionen in der ASP.NET Core-Web-API

16.806 Beiträge seit 2008
vor 2 Jahren

..aber trotzdem empfohlen 🙂
Aber generell gibts eh viele Empfehlungen, zB auch die Verwendung von entsprechenden Request Models und Model Bindern. Da kann man eh viel machen.

309 Beiträge seit 2020
vor 2 Jahren

Habe es nur übernommen, denke der Grundgedanke sollte aber für ihn klar sein:

Tutorial: Erstellen einer Web-API mit ASP.NET Core

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Hmmm, also entweder habe ich mich jetzt total in die falsche Richtung verbissen oder es ist mit Flurl wirklich nicht möglich in C# eine Rückmeldung von PHP zu erhalten oder ich mache was grundlegend falsch mit der Libray. Ich habe folgenden PHP Code ergänzt:


	# Prüfen, ob es die Seriennummer in der Datenbank gibt.
	$db_read = "Select computerSerial from db_computer where computerSerial=?";
	$db_prepare = $db_connect->prepare($db_read);
	$data = array($_POST['computerSerial']);
	$db_prepare->execute($data);

	$number = $db_prepare->rowCount();
	# Falls kein Eintrag gefunden wurde, Vorgang abbrechen
	if ($number = 0) {
		echo "Computer nicht in der Datenbank";
[...]

Zumindest das "Computer nicht in der Datenbank" hätte ich gerne als MessageBox.Show in C#. Wenn MySQL selbst einen Fehler wirft, beispielsweise weil man Mist in der Syntax oder so gebaut hat, wäre es natürlich auch schön das zu bekommen.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

16.806 Beiträge seit 2008
vor 2 Jahren

hätte ich gerne als MessageBox.Show in C#.

Das wirste nich hinbekommen, mit keiner Webtechnologie, die auf dem Server ausgeführt wird.
So funktionieren Server-Anwendungen nicht; die können keine Message Box auf dem Client ausspucken.

Glaube Du hast eine etwas falsche Vorstellung, wie Software funktioniert - und wo Dein Code ausgführt wird 🙂

Deine REST API müsste den Fehler als Code und Body dem Client mitteilen.
Der Client kann dann auf Deinem PC laufen - und dort die Meldung ausgeben.
Im Endeffekt eine Kombination auf Basis verschiedener Technologien. Aber mit Magie gehts leider nicht; da musst durch.

Am Ende ist das nicht viel Code; aber Du musst schon einige Konzepte lernen.

309 Beiträge seit 2020
vor 2 Jahren

Was steht denn in deinem ResponseString?


var responseString = await "https://example.tld/update_db.php"
                .PostUrlEncodedAsync(...
                })
                .ReceiveString();

Ohne die Library zu kennen hört es sich für mich an, als würde das den Content der Antwort zurückgeben.

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Cool, das funktioniert. Aber ob die anderen wollten, dass ich das erfahre? 😁

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

309 Beiträge seit 2020
vor 2 Jahren

Cool, das funktioniert. Aber ob die anderen wollten, dass ich das erfahre? 😁

Naja dir gings ja um Sicherheit, die haben schon recht dass man es besser machen kann.
Aber wenn euch im Unternehmen so ein Gebastel reicht dann bitte 😁

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor 2 Jahren

Erstmal soll mir das reichen, ja. Dennoch wird es mit Fertigstellung der Version 1 an die Version 2 gehen.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6