Manipulatie van Paypal transacties

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

GaMer B

GaMer B

24/10/2007 16:44:00
Quote Anchor link
Dit topic is niet echt een vraag, maar meer een "heeft-iemand-een-andere-oplossing-of-iets-dergelijks" topic.
Ik ben de laatste tijd veel bezig met de Paypal API. Aangezien ik een eigen bestel-wizard heb, wil ik dus dat bedragen variabel worden gemaakt. Dit kun je doen door geen encryptie op de HTML code van de door Paypal gegenereerde code te zetten, waardoor je zelf de 'amount' van het bedrag kunt instellen.

Dit weet ik allemaal, dat is niet het probleem. Het probleem is meer algemeen:
Ook al heb je encryptie op de HTML code die door Paypal gegenereerd is (die van een Buy now button of Cart), je kan nog altijd de verzonden data manipuleren van buitenaf, bijvoorbeeld door een plugin van Firefox. Zonder encryptie op de HTML code is het helemaal gesneden koek voor hackers.
Je kunt het deel: amount_money van de POST array die naar Paypal wordt verzonden veranderen naar bijvoorbeeld 0.01 (1 cent) en tada! Je hebt iets gekocht voor 1 cent.

Nu weet ik wel dat je bijvoorbeeld als verkoper van je producten alles handmatig kunt valideren, dus wanneer de prijs klopt, de koper e-mailen. Maar dit vind ik eigenlijk niet kunnen. Is dit niet fraude? En is dit misschien op te lossen door die POST array die naar Paypal gaat te versleutelen ofzo?

Gaarne jullie mening,
GaMer13
 
PHP hulp

PHP hulp

08/11/2024 20:11:31
 
Jacco Engel

Jacco Engel

24/10/2007 16:46:00
Quote Anchor link
Ik weet niets van de paypal api af dus brainstormpje:

Voor je alles verzend een script schrijven wat gewoon alle prijzen in de DB controleerd met de prijzen op de rekening ?

Just my 2 centzzzzz

Jacco
 
GaMer B

GaMer B

24/10/2007 16:48:00
Quote Anchor link
Jacco schreef op 24.10.2007 16:46:
Voor je alles verzend een script schrijven wat gewoon alle prijzen in de DB controleerd met de prijzen op de rekening ?

Dus eigenlijk een tussen-pagina die dan de geposte data doet valideren a.d.h.v. het product en dan met uhm... ... (hoe heet die extentie van PHP ook al weer om een POST request uit te voeren op een pagina, nja, in ieder geval op die manier) dan een POST request op die pagina die eigenlijk bedoeld was?
Kan misschien wel een goede oplossing zijn.
 
Jacco Engel

Jacco Engel

24/10/2007 16:52:00
Quote Anchor link
Weet er niet veel van zoals ik al zei en dat is eigenlijk het enige dat ik kan bedenken :$

Edit:

Onderstaand :
True

en als je het goed script minder fout gevoelig dan iemand die het manual moet gaan controleren. Want als ik voor de grap alleen de komma iets naar voren zet en die persoon zit een beetje te dutten ben ik benieuwd of hij/zij het wel ziet :)
Gewijzigd op 01/01/1970 01:00:00 door Jacco Engel
 
GaMer B

GaMer B

24/10/2007 16:53:00
Quote Anchor link
Jacco schreef op 24.10.2007 16:52:
Weet er niet veel van zoals ik al zei en dat is eigenlijk het enige dat ik kan bedenken :$

Het is in ieder geval iets en beter dan "manual validation".
 
Kumkwat Trender

Kumkwat Trender

24/10/2007 17:01:00
Quote Anchor link
@gamer waarvoor heb je het eigenlijk nodig? voor voirea :S

"Je kunt het deel: amount_money van de POST array die naar Paypal wordt verzonden veranderen naar bijvoorbeeld 0.01 (1 cent) en tada! Je hebt iets gekocht voor 1 cent."

kun je dat niet controlleren met php zelf?
als er gepost wordt 1 cent dat het pagina geblokeerd wordt of zow dergelijke...
 
Jacco Engel

Jacco Engel

24/10/2007 17:07:00
Quote Anchor link
Peter als ik dat weet ga ik vrolijk 2 of 3 of 4 of (willekeurig getal dat lager is dan de vraagprijs) posten :)
 
GaMer B

GaMer B

24/10/2007 17:09:00
Quote Anchor link
Peter schreef op 24.10.2007 17:01:
@gamer waarvoor heb je het eigenlijk nodig? voor voirea :S

Euh, waarom moet jij dat weten? Doet er ook niet toe....

Peter schreef op 24.10.2007 17:01:
"Je kunt het deel: amount_money van de POST array die naar Paypal wordt verzonden veranderen naar bijvoorbeeld 0.01 (1 cent) en tada! Je hebt iets gekocht voor 1 cent."

kun je dat niet controlleren met php zelf?
als er gepost wordt 1 cent dat het pagina geblokeerd wordt of zow dergelijke...

Dat stelde Jacco al voor.
Maar nu bedenk ik me opeens iets he, wanneer je een tussen-pagina erbij zet, dan moet je evengoed alle data weer doorsturen naar Paypal, dus ben je weer bij af :S

EDIT: Hier heb je een voorbeeld pagina (van een bedrijf: Rapidshare.com). Hun broncode is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form target="_blank" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input name="cmd" value="_xclick" type="hidden">
<input name="business" value="[email protected]" type="hidden">
<input name="item_name" value="RapidShare.com - PREMIUM (48 hours short-term)" type="hidden">
<input name="item_number" value="14" type="hidden">
<!-- HET BEDRAG -->
<input name="amount" value="4.50" type="hidden">
<!-- HET BEDRAG -->
<input name="page_style" value="RapidShare" type="hidden">
<input name="no_shipping" value="1" type="hidden">

<input name="return" value="https://ssl.rapidshare.com/cgi-bin/paypalok.cgi" type="hidden">
<input name="no_note" value="1" type="hidden">
<input name="currency_code" value="EUR" type="hidden">
<input name="lc" value="US" type="hidden">
<input name="bn" value="PP-BuyNowBF" type="hidden">
<input src="http://images.rapidshare.com/img/paypal_buy.gif" type="image">
</form>

Ik heb het eens onderschept en ik kan inderdaad veranderen naar 0.01 euro. Echter, hun procedure is als volgt:
1. Ze krijgen de betaling binnen op hun Paypal account.
2. Ze valideren handmatig het bedrag voor het desbetreffende item_number en item_name (zie broncode).
3. Als het klopt, stuur mailtje met PREMIUM account gegevens naar de koper.

Maar de procedure is zo... omslachtig en niet automatisch. Ik denk dat er gewoon niks anders op zit dan gewoon alles handmatig te gaan valideren :(
Gewijzigd op 01/01/1970 01:00:00 door GaMer B
 
Jacco Engel

Jacco Engel

24/10/2007 17:13:00
Quote Anchor link
Je controleerd toch zowiezo de data die je naar PayPal stuurd neem ik aan? Waarom zou je er niet een simpele checkPrize functie bij kunnen maken in de trant van :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
function checkPrize($item_id)
{

$query = "SELECT prijs FROM artikelen WHERE artikel_id = ".$item_id;
$result = mysql_query($query) ;
$prijs = mysql_fetch_assoc($result) ;
$prijs = $prijs["prijs"] ;
return $prijs
}

if ($_POST["prijs"] == checkPrijs($_POST["artikel_id"]))
{

//doe je paypal ding
}
else
{
//gebruiker blokkeren, bannen, zn computer laten crashen of wat je ook wil doen als een gebruik zich niet gedraagt
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Jacco Engel
 
GaMer B

GaMer B

24/10/2007 17:19:00
Quote Anchor link
@Jacco, ja precies. Maar wat je nu dus in het gedeelte: // doe je paypal ding moet zetten is het volgende:
Stuur de gegevens (product ID, product prijs etc.) door aan Paypal, zodat Paypal het kan verwerken.

Maar (hopelijk zie je het probleem al weer), wederom kun je de post variabelen weer bewerken (die van de transactie tussen: tussen-pagina en Paypal). XD

Zo kun je door blijven gaan :P.
 
Jacco Engel

Jacco Engel

24/10/2007 17:20:00
Quote Anchor link
Pm wel ff met je :)
 
Jurgen assaasas

Jurgen assaasas

24/10/2007 18:16:00
Quote Anchor link
Kun je ze niet encrypten nadat de volledige HTML is gemaakt incl het gewenste bedrag?
 
GaMer B

GaMer B

24/10/2007 18:19:00
Quote Anchor link
Jurgen schreef op 24.10.2007 18:16:
Kun je ze niet encrypten nadat de volledige HTML is gemaakt incl het gewenste bedrag?

Ik kwam er net achter, dat wanneer je het WEL ge-encrypted hebt, je de POST array niet kunt ontleden in die plugin van Firefox. Je krijgt alleen de encrypted string (van wel 50 regels) te zien.

Ik vraag me alleen af wat voor een encryptie techniek het is :S
Het begint zo:
Quote:
-----BEGIN PKCS7-----


Even googlen dus..: BEGIN PKCS7

EDIT: Okej, het blijkt dus iets van OpenSSL te zijn...
Gewijzigd op 01/01/1970 01:00:00 door GaMer B
 
Onbekend Onbekend

Onbekend Onbekend

24/10/2007 18:26:00
 
Frank -

Frank -

24/10/2007 18:36:00
Quote Anchor link
Quote:
2. Ze valideren handmatig het bedrag voor het desbetreffende item_number en item_name (zie broncode).
Ik mag toch hopen dat ze niet zo stom zijn, dat zou fouten in de hand werken.

Zoek eens op IPN, dat lijkt me nuttiger dan het wiel proberen uit te vinden.

Wat jij naar PayPal stuurt en wat de klant bij PayPal betaalt, is niet overdreven belangrijk. Wat wél belangrijk is, is dat de betaling die jij ontvangt, overeenkomt met de bestelling die is gedaan. Daar kan IPN je bij helpen.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
 
GaMer B

GaMer B

24/10/2007 18:46:00
Quote Anchor link
Thnx, ik zal eens wat rondneuzen.
 
GaMer B

GaMer B

26/10/2007 20:45:00
Quote Anchor link
De oplossing gevonden:

EDIT: Verdere info over het creëren van de .pem bestanden kun je hier vinden.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<?php
/*

  The PayPal class implements the dynamic encryption of PayPal "buy now"
  buttons using the PHP openssl functions. (This evades the ISP restriction
  on executing the external "openssl" utility.)

  Original Author: Ivor Durham ([email protected])  Edited by PayPal_Ahmad  (Nov. 04, 2006)
  Posted originally on PDNCommunity:  http://www.pdncommunity.com/pdn/board/message?board.id=ewp&message.id=87#M87

  Using the orginal code on PHP 4.4.4 on WinXP Pro I was getting the following error:
  
  "The email address for the business is not present in the encrypted blob. Please contact your merchant"
  
  I modified and cleaned up a few things to resolve the error - this was tested on PHP 4.4.4 + OpenSSL on WinXP Pro
  Example usage:
*/


$sandbox = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
//$live = 'https://www.paypal.com/cgi-bin/webscr';  

$TempFileDirectory = '/tmp'; //path to temp file
$myPublicCertificate = 'my-pubcert.pem'; //path to your public certificate
$myPrivateKey = 'my-prvkey.pem'; //path to your private key
$CertificateID = '4JWENTD98RL7W'; //certificate id generated by PayPal
$PayPalPublicCertificate = 'paypal_cert_pem.txt'; //PayPal public certificate

$paypal = &new PayPalEWP();

$paypal->setTempFileDirectory($TempFileDirectory);
$paypal->setCertificate($myPublicCertificate, $myPrivateKey);
$paypal->setCertificateID($CertificateID);
$paypal->setPayPalCertificate($PayPalPublicCertificate);

$parameters = array(
'cmd' => '_xclick',
'business' => '[email protected]', //confirmed email address on your PayPal account
'item_number' => 1,
'amount' => 10.15,
'currency_code' => 'EURO', // standard USD
'no_shipping' => 1,
'no_note' => 1,
);

    
$encryptedButton = $paypal->encryptButton($parameters);
    
echo 'Item: <b>1</b> terwaarde van: <b>'.$price.'</b> euro
<form action="'
. $sandbox . '" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="submit" value="Buy item 1">
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7----- '
.$encryptedButton.'-----END PKCS7-----">
</form>'
;

class PayPalEWP {
    
    var
$certificate;    // Certificate resource
    var $certificateFile;    // Path to the certificate file

    var $privateKey;    // Private key resource (matching certificate)
    var $privateKeyFile;    // Path to the private key file

    var $paypalCertificate;    // PayPal public certificate resource
    var $paypalCertificateFile;    // Path to PayPal public certificate file
    var $certificateID; // ID assigned by PayPal to the $certificate.

    var $tempFileDirectory;
    
    //setCertificateID: Sets the ID assigned by PayPal to the client certificate
    //$id - The certificate ID assigned when the certificate was uploaded to PayPal


    function setCertificateID($id) {
        $this->certificateID = $id;
    }

  
    //setCertificate: set the client certificate and private key pair.
    //$certificateFilename - The path to the client certificate

    //$keyFilename - The path to the private key corresponding to the certificate
    //Returns: TRUE if the private key matches the certificate.


    function setCertificate($certificateFilename, $privateKeyFilename) {
        $result = false;

        if (is_readable($certificateFilename) && is_readable($privateKeyFilename))
        {

            $certificate=null;
            $handle=fopen($certificateFilename, "r");
            $size=filesize($certificateFilename);
            $certificate=fread($handle,$size);
            fclose($handle);

            $privateKey=null;              
            $handle=fopen($privateKeyFilename,"r");
            $size=filesize($privateKeyFilename);
            $privateKey=fread($handle, $size);
            fclose($handle);
        
              if (($certificate !== false) && ($privateKey !== false) && openssl_x509_check_private_key($certificate, $privateKey)) {
                $this->certificate = $certificate;
                $this->certificateFile = $certificateFilename;
                $this->privateKey = $privateKey;
                $this->privateKeyFile = $privateKeyFilename;
                $result = true;
              }
        }


        return $result;
    }


    //setPayPalCertificate: Sets the PayPal certificate
    //$fileName - The path to the PayPal certificate.
    //Returns: TRUE iff the certificate is read successfully, FALSE otherwise.


    function setPayPalCertificate($fileName) {
        if (is_readable($fileName)) {
            $handle=null;
            $certificate=null;
            $size=null;
            
            $handle=fopen($fileName, "r");
            if (!$handle){
                echo 'Paypal cert could not be opened';
            }

            $size=filesize($fileName);
        
            $certificate=fread($handle, $size);
            if (!$certificate){
                echo 'Paypal cert could not be read';
            }

            fclose($handle);

            if ($certificate !== false) {
                $this->paypalCertificate = $certificate;
                $this->paypalCertificateFile = $fileName;
                return true;
            }
        }

        return false;
    }


    //setTempFileDirectory: Sets the directory into which temporary files are written.
    //$directory - Directory in which to write temporary files.
    //Returns: TRUE iff directory is usable.


    function setTempFileDirectory($directory) {
          if (is_dir($directory) && is_writable($directory)) {
            $this->tempFileDirectory = $directory;
              return true;
        }
else {
              return false;
          }
      }


    //encryptButton: Using the previously set certificates and tempFileDirectory
    //encrypt the button information.

    //$parameters - Array with parameter names as keys.
    //Returns: The encrypted string for the _s_xclick button form field.


    function encryptButton($parameters) {
        // Check encryption data is available.

        if (($this->certificateID == '') || !isset($this->certificate) || !isset($this->paypalCertificate)) {
            return false;
        }


        $clearText = '';
        $encryptedText = '';

        // initialize data.
        $data = "cert_id=" . $this->certificateID . "\n";;
        foreach($parameters as $k => $v)
            $d[] = "$k=$v";
            $data .= join("\n", $d);

        $dataFile = tempnam($this->tempFileDirectory, 'data');
        
        $out = fopen("{$dataFile}_data.txt", 'wb');
        fwrite($out, $data);
        fclose($out);
        
        $out=fopen("{$dataFile}_signed.txt", "w+");

        if (!openssl_pkcs7_sign("{$dataFile}_data.txt", "{$dataFile}_signed.txt", $this->certificate, $this->privateKey, array(), PKCS7_BINARY)) {
            return false;
        }

        fclose($out);

        $signedData = explode("\n\n", file_get_contents("{$dataFile}_signed.txt"));

        $out = fopen("{$dataFile}_signed.txt", 'wb');
        fwrite($out, base64_decode($signedData[1]));
        fclose($out);

        if (!openssl_pkcs7_encrypt("{$dataFile}_signed.txt", "{$dataFile}_encrypted.txt", $this->paypalCertificate, array(), PKCS7_BINARY)) {
            return false;
        }


        $encryptedData = explode("\n\n", file_get_contents("{$dataFile}_encrypted.txt"));

        $encryptedText = $encryptedData[1];

        @
unlink($dataFile);  
        @
unlink("{$dataFile}_data.txt");
        @
unlink("{$dataFile}_signed.txt");
        @
unlink("{$dataFile}_encrypted.txt");

        return $encryptedText;
    }
}

?>
Gewijzigd op 01/01/1970 01:00:00 door GaMer B
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.